summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-08-21 21:54:57 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-08-21 21:54:57 +0000
commit584f35dcc621f5877732cf310c310570c021c31d (patch)
tree6dd2b5612d3a41949ca87828c7cf27713e059675 /src/live_effects
parentNot sure about this changes :( (diff)
parentindentation and whitespace fixes (diff)
downloadinkscape-584f35dcc621f5877732cf310c310570c021c31d.tar.gz
inkscape-584f35dcc621f5877732cf310c310570c021c31d.zip
update to trunk
(bzr r13645.1.108)
Diffstat (limited to 'src/live_effects')
-rw-r--r--src/live_effects/lpe-angle_bisector.cpp2
-rw-r--r--src/live_effects/lpe-bendpath.h3
-rw-r--r--src/live_effects/lpe-bspline.cpp240
-rw-r--r--src/live_effects/lpe-bspline.h13
-rw-r--r--src/live_effects/lpe-simplify.cpp1
-rw-r--r--src/live_effects/lpe-spiro.cpp16
-rw-r--r--src/live_effects/lpe-spiro.h2
-rw-r--r--src/live_effects/spiro-converters.cpp32
-rw-r--r--src/live_effects/spiro-converters.h24
-rw-r--r--src/live_effects/spiro.cpp15
10 files changed, 164 insertions, 184 deletions
diff --git a/src/live_effects/lpe-angle_bisector.cpp b/src/live_effects/lpe-angle_bisector.cpp
index 95a81c763..900d29e3a 100644
--- a/src/live_effects/lpe-angle_bisector.cpp
+++ b/src/live_effects/lpe-angle_bisector.cpp
@@ -38,7 +38,7 @@ public:
virtual Geom::Point knot_get() const;
};
-} // namespace TtC
+} // namespace AB
LPEAngleBisector::LPEAngleBisector(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h
index 16b8c6137..0871d532e 100644
--- a/src/live_effects/lpe-bendpath.h
+++ b/src/live_effects/lpe-bendpath.h
@@ -39,9 +39,8 @@ public:
virtual void resetDefaults(SPItem const* item);
-
-private:
PathParam bend_path;
+private:
ScalarParam prop_scale;
BoolParam scale_y_rel;
BoolParam vertical_pattern;
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index c2a2d080e..019584943 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -16,10 +16,12 @@
namespace Inkscape {
namespace LivePathEffect {
-const double HANDLE_CUBIC_GAP = 0.01;
+const double HANDLE_CUBIC_GAP = 0.001;
const double NO_POWER = 0.0;
const double DEFAULT_START_POWER = 0.3334;
const double DEFAULT_END_POWER = 0.6667;
+Geom::PathVector hp;
+void sp_bspline_drawHandle(Geom::Point p, double helper_size);
LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject)
: Effect(lpeobject),
@@ -67,15 +69,115 @@ void LPEBSpline::doOnApply(SPLPEItem const* lpeitem)
}
}
+void
+LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
+{
+ hp_vec.push_back(hp);
+}
+
+Gtk::Widget *LPEBSpline::newWidget()
+{
+ // use manage here, because after deletion of Effect object, others might
+ // still be pointing to this widget.
+ Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
+
+ vbox->set_border_width(5);
+ std::vector<Parameter *>::iterator it = param_vector.begin();
+ while (it != param_vector.end()) {
+ if ((*it)->widget_is_visible) {
+ Parameter *param = *it;
+ Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
+ if (param->param_key == "weight") {
+ Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0));
+ Gtk::Button *default_weight =
+ Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight"))));
+ default_weight->signal_clicked()
+ .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight));
+ buttons->pack_start(*default_weight, true, true, 2);
+ Gtk::Button *make_cusp =
+ Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp"))));
+ make_cusp->signal_clicked()
+ .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp));
+ buttons->pack_start(*make_cusp, true, true, 2);
+ vbox->pack_start(*buttons, true, true, 2);
+ }
+ if (param->param_key == "weight" || param->param_key == "steps") {
+ Inkscape::UI::Widget::Scalar *widg_registered =
+ Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg));
+ widg_registered->signal_value_changed()
+ .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight));
+ widg = dynamic_cast<Gtk::Widget *>(widg_registered);
+ if (widg) {
+ Gtk::HBox * hbox_weight_steps = dynamic_cast<Gtk::HBox *>(widg);
+ std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children();
+ Gtk::Entry* entry_widget = dynamic_cast<Gtk::Entry *>(childList[1]);
+ entry_widget->set_width_chars(6);
+ }
+ }
+ if (param->param_key == "only_selected") {
+ Gtk::CheckButton *widg_registered =
+ Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
+ widg = dynamic_cast<Gtk::Widget *>(widg_registered);
+ }
+ if (param->param_key == "ignore_cusp") {
+ Gtk::CheckButton *widg_registered =
+ Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
+ widg = dynamic_cast<Gtk::Widget *>(widg_registered);
+ }
+ Glib::ustring *tip = param->param_getTooltip();
+ if (widg) {
+ vbox->pack_start(*widg, true, true, 2);
+ if (tip) {
+ widg->set_tooltip_text(*tip);
+ } else {
+ widg->set_tooltip_text("");
+ widg->set_has_tooltip(false);
+ }
+ }
+ }
+
+ ++it;
+ }
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
+void LPEBSpline::toDefaultWeight()
+{
+ changeWeight(DEFAULT_START_POWER);
+}
+
+void LPEBSpline::toMakeCusp()
+{
+ changeWeight(NO_POWER);
+}
+
+void LPEBSpline::toWeight()
+{
+ changeWeight(weight);
+}
+
+void LPEBSpline::changeWeight(double weight_ammount)
+{
+ SPPath *path = dynamic_cast<SPPath *>(sp_lpe_item);
+ if(path) {
+ SPCurve *curve = path->get_curve_for_edit();
+ doBSplineFromWidget(curve, weight_ammount);
+ gchar *str = sp_svg_write_path(curve->get_pathvector());
+ path->getRepr()->setAttribute("inkscape:original-d", str);
+ }
+}
+
void LPEBSpline::doEffect(SPCurve *curve)
{
+ sp_bspline_do_effect(curve, helper_size);
+}
+void sp_bspline_do_effect(SPCurve *curve, double helper_size)
+{
if (curve->get_segment_count() < 1) {
return;
}
- // Make copy of old path as it is changed during processing
Geom::PathVector const original_pathv = curve->get_pathvector();
-
curve->reset();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
@@ -99,20 +201,6 @@ void LPEBSpline::doEffect(SPCurve *curve)
Geom::D2<Geom::SBasis> sbasis_out;
Geom::D2<Geom::SBasis> sbasis_helper;
Geom::CubicBezier const *cubic = NULL;
- if (path_it->closed()) {
- // if the path is closed, maybe we have to stop a bit earlier because the
- // closing line segment has zerolength.
- const Geom::Curve &closingline =
- path_it->back_closed(); // the closing line segment is always of type
- // Geom::LineSegment.
- if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
- // closingline.isDegenerate() did not work, because it only checks for
- // *exact* zero length, which goes wrong for relative coordinates and
- // rounding errors...
- // the closing line segment has zero-length. So stop before that one!
- curve_endit = path_it->end_open();
- }
- }
curve_n->moveto(curve_it1->initialPoint());
while (curve_it1 != curve_endit) {
SPCurve *in = new SPCurve();
@@ -209,12 +297,11 @@ void LPEBSpline::doEffect(SPCurve *curve)
curve_n->curveto(point_at1, point_at2, node);
}
if(!are_near(node,curve_it1->finalPoint()) && helper_size > 0.0) {
- drawHandle(node, helper_size);
+ sp_bspline_drawHandle(node, helper_size);
}
++curve_it1;
++curve_it2;
}
- //y cerramos la curva
if (path_it->closed()) {
curve_n->closepath_current();
}
@@ -228,8 +315,8 @@ void LPEBSpline::doEffect(SPCurve *curve)
}
}
-void
-LPEBSpline::drawHandle(Geom::Point p, double helper_size)
+
+void sp_bspline_drawHandle(Geom::Point p, double helper_size)
{
char const * svgd = "M 1,0.5 A 0.5,0.5 0 0 1 0.5,1 0.5,0.5 0 0 1 0,0.5 0.5,0.5 0 0 1 0.5,0 0.5,0.5 0 0 1 1,0.5 Z";
Geom::PathVector pathv = sp_svg_read_pathv(svgd);
@@ -240,103 +327,6 @@ LPEBSpline::drawHandle(Geom::Point p, double helper_size)
hp.push_back(pathv[0]);
}
-void
-LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
-{
- hp_vec.push_back(hp);
-}
-Gtk::Widget *LPEBSpline::newWidget()
-{
- // use manage here, because after deletion of Effect object, others might
- // still be pointing to this widget.
- Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
-
- vbox->set_border_width(5);
- std::vector<Parameter *>::iterator it = param_vector.begin();
- while (it != param_vector.end()) {
- if ((*it)->widget_is_visible) {
- Parameter *param = *it;
- Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
- if (param->param_key == "weight") {
- Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0));
- Gtk::Button *default_weight =
- Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight"))));
- default_weight->signal_clicked()
- .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight));
- buttons->pack_start(*default_weight, true, true, 2);
- Gtk::Button *make_cusp =
- Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp"))));
- make_cusp->signal_clicked()
- .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp));
- buttons->pack_start(*make_cusp, true, true, 2);
- vbox->pack_start(*buttons, true, true, 2);
- }
- if (param->param_key == "weight" || param->param_key == "steps") {
- Inkscape::UI::Widget::Scalar *widg_registered =
- Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg));
- widg_registered->signal_value_changed()
- .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight));
- widg = dynamic_cast<Gtk::Widget *>(widg_registered);
- if (widg) {
- Gtk::HBox * hbox_weight_steps = dynamic_cast<Gtk::HBox *>(widg);
- std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children();
- Gtk::Entry* entry_widget = dynamic_cast<Gtk::Entry *>(childList[1]);
- entry_widget->set_width_chars(6);
- }
- }
- if (param->param_key == "only_selected") {
- Gtk::CheckButton *widg_registered =
- Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
- widg = dynamic_cast<Gtk::Widget *>(widg_registered);
- }
- if (param->param_key == "ignore_cusp") {
- Gtk::CheckButton *widg_registered =
- Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
- widg = dynamic_cast<Gtk::Widget *>(widg_registered);
- }
- Glib::ustring *tip = param->param_getTooltip();
- if (widg) {
- vbox->pack_start(*widg, true, true, 2);
- if (tip) {
- widg->set_tooltip_text(*tip);
- } else {
- widg->set_tooltip_text("");
- widg->set_has_tooltip(false);
- }
- }
- }
-
- ++it;
- }
- return dynamic_cast<Gtk::Widget *>(vbox);
-}
-
-void LPEBSpline::toDefaultWeight()
-{
- changeWeight(DEFAULT_START_POWER);
-}
-
-void LPEBSpline::toMakeCusp()
-{
- changeWeight(NO_POWER);
-}
-
-void LPEBSpline::toWeight()
-{
- changeWeight(weight);
-}
-
-void LPEBSpline::changeWeight(double weight_ammount)
-{
- SPPath *path = dynamic_cast<SPPath *>(sp_lpe_item);
- if(path) {
- SPCurve *curve = path->get_curve_for_edit();
- doBSplineFromWidget(curve, weight_ammount);
- gchar *str = sp_svg_write_path(curve->get_pathvector());
- path->getRepr()->setAttribute("inkscape:original-d", str);
- }
-}
-
void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
{
using Geom::X;
@@ -366,20 +356,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
Geom::D2<Geom::SBasis> sbasis_in;
Geom::D2<Geom::SBasis> sbasis_out;
Geom::CubicBezier const *cubic = NULL;
- if (path_it->closed()) {
- // if the path is closed, maybe we have to stop a bit earlier because the
- // closing line segment has zerolength.
- const Geom::Curve &closingline =
- path_it->back_closed(); // the closing line segment is always of type
- // Geom::LineSegment.
- if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
- // closingline.isDegenerate() did not work, because it only checks for
- // *exact* zero length, which goes wrong for relative coordinates and
- // rounding errors...
- // the closing line segment has zero-length. So stop before that one!
- curve_endit = path_it->end_open();
- }
- }
curve_n->moveto(curve_it1->initialPoint());
while (curve_it1 != curve_endit) {
SPCurve *in = new SPCurve();
diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h
index fc0f66353..033e85cf0 100644
--- a/src/live_effects/lpe-bspline.h
+++ b/src/live_effects/lpe-bspline.h
@@ -25,14 +25,13 @@ public:
virtual void doOnApply(SPLPEItem const* lpeitem);
virtual void doEffect(SPCurve *curve);
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
- void drawHandle(Geom::Point p, double radiusHelperNodes);
- virtual void doBSplineFromWidget(SPCurve *curve, double value);
+ void doBSplineFromWidget(SPCurve *curve, double value);
void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec);
virtual Gtk::Widget *newWidget();
- virtual void changeWeight(double weightValue);
- virtual void toDefaultWeight();
- virtual void toMakeCusp();
- virtual void toWeight();
+ void changeWeight(double weightValue);
+ void toDefaultWeight();
+ void toMakeCusp();
+ void toWeight();
// TODO make this private
ScalarParam steps;
@@ -42,12 +41,12 @@ private:
BoolParam ignore_cusp;
BoolParam only_selected;
ScalarParam weight;
- Geom::PathVector hp;
LPEBSpline(const LPEBSpline &);
LPEBSpline &operator=(const LPEBSpline &);
};
+void sp_bspline_do_effect(SPCurve *curve, double helper_size);
} //namespace LivePathEffect
} //namespace Inkscape
diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp
index 265192a17..f6842a030 100644
--- a/src/live_effects/lpe-simplify.cpp
+++ b/src/live_effects/lpe-simplify.cpp
@@ -82,6 +82,7 @@ LPESimplify::newWidget()
{
// use manage here, because after deletion of Effect object, others might still be pointing to this widget.
Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) );
+
vbox->set_border_width(5);
vbox->set_homogeneous(false);
vbox->set_spacing(2);
diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp
index eefd25c7d..0d42596b2 100644
--- a/src/live_effects/lpe-spiro.cpp
+++ b/src/live_effects/lpe-spiro.cpp
@@ -37,6 +37,10 @@ LPESpiro::~LPESpiro()
void
LPESpiro::doEffect(SPCurve * curve)
{
+ sp_spiro_do_effect(curve);
+}
+
+void sp_spiro_do_effect(SPCurve *curve){
using Geom::X;
using Geom::Y;
@@ -54,7 +58,7 @@ LPESpiro::doEffect(SPCurve * curve)
// start of path
{
- Geom::Point p = path_it->front().pointAt(0);
+ Geom::Point p = path_it->initialPoint();
path[ip].x = p[X];
path[ip].y = p[Y];
path[ip].ty = '{' ; // for closed paths, this is overwritten
@@ -64,17 +68,7 @@ LPESpiro::doEffect(SPCurve * curve)
// midpoints
Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
-
Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
- if (path_it->closed()) {
- // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength.
- const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment.
- if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
- // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors...
- // the closing line segment has zero-length. So stop before that one!
- curve_endit = path_it->end_open();
- }
- }
while ( curve_it2 != curve_endit )
{
diff --git a/src/live_effects/lpe-spiro.h b/src/live_effects/lpe-spiro.h
index edce42280..c8aba53d9 100644
--- a/src/live_effects/lpe-spiro.h
+++ b/src/live_effects/lpe-spiro.h
@@ -27,6 +27,8 @@ private:
LPESpiro& operator=(const LPESpiro&);
};
+void sp_spiro_do_effect(SPCurve *curve);
+
}; //namespace LivePathEffect
}; //namespace Inkscape
diff --git a/src/live_effects/spiro-converters.cpp b/src/live_effects/spiro-converters.cpp
index f116d5256..ee214704c 100644
--- a/src/live_effects/spiro-converters.cpp
+++ b/src/live_effects/spiro-converters.cpp
@@ -21,43 +21,49 @@
namespace Spiro {
void
-ConverterSPCurve::moveto(double x, double y, bool is_open)
+ConverterSPCurve::moveto(double x, double y)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_curve.moveto(x, y);
- if (!is_open) {
- _curve.closepath();
- }
} else {
SPIRO_G_MESSAGE("Spiro: moveto not finite");
}
}
void
-ConverterSPCurve::lineto(double x, double y)
+ConverterSPCurve::lineto(double x, double y, bool close_last)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_curve.lineto(x, y);
+ if (close_last) {
+ _curve.closepath();
+ }
} else {
SPIRO_G_MESSAGE("Spiro: lineto not finite");
}
}
void
-ConverterSPCurve::quadto(double xm, double ym, double x3, double y3)
+ConverterSPCurve::quadto(double xm, double ym, double x3, double y3, bool close_last)
{
if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) {
_curve.quadto(xm, ym, x3, y3);
+ if (close_last) {
+ _curve.closepath();
+ }
} else {
SPIRO_G_MESSAGE("Spiro: quadto not finite");
}
}
void
-ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3)
+ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last)
{
if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) {
_curve.curveto(x1, y1, x2, y2, x3, y3);
+ if (close_last) {
+ _curve.closepath();
+ }
} else {
SPIRO_G_MESSAGE("Spiro: curveto not finite");
}
@@ -71,41 +77,43 @@ ConverterPath::ConverterPath(Geom::Path &path)
}
void
-ConverterPath::moveto(double x, double y, bool is_open)
+ConverterPath::moveto(double x, double y)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_path.start(Geom::Point(x, y));
- _path.close(!is_open);
} else {
SPIRO_G_MESSAGE("spiro moveto not finite");
}
}
void
-ConverterPath::lineto(double x, double y)
+ConverterPath::lineto(double x, double y, bool close_last)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_path.appendNew<Geom::LineSegment>( Geom::Point(x, y) );
+ _path.close(close_last);
} else {
SPIRO_G_MESSAGE("spiro lineto not finite");
}
}
void
-ConverterPath::quadto(double xm, double ym, double x3, double y3)
+ConverterPath::quadto(double xm, double ym, double x3, double y3, bool close_last)
{
if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) {
_path.appendNew<Geom::QuadraticBezier>(Geom::Point(xm, ym), Geom::Point(x3, y3));
+ _path.close(close_last);
} else {
SPIRO_G_MESSAGE("spiro quadto not finite");
}
}
void
-ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3)
+ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last)
{
if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) {
_path.appendNew<Geom::CubicBezier>(Geom::Point(x1, y1), Geom::Point(x2, y2), Geom::Point(x3, y3));
+ _path.close(close_last);
} else {
SPIRO_G_MESSAGE("spiro curveto not finite");
}
diff --git a/src/live_effects/spiro-converters.h b/src/live_effects/spiro-converters.h
index 90855d2d6..6182a5dcd 100644
--- a/src/live_effects/spiro-converters.h
+++ b/src/live_effects/spiro-converters.h
@@ -11,10 +11,10 @@ public:
ConverterBase() {};
virtual ~ConverterBase() {};
- virtual void moveto(double x, double y, bool is_open) = 0;
- virtual void lineto(double x, double y) = 0;
- virtual void quadto(double x1, double y1, double x2, double y2) = 0;
- virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3) = 0;
+ virtual void moveto(double x, double y) = 0;
+ virtual void lineto(double x, double y, bool close_last) = 0;
+ virtual void quadto(double x1, double y1, double x2, double y2, bool close_last) = 0;
+ virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) = 0;
};
@@ -27,10 +27,10 @@ public:
: _curve(curve)
{}
- virtual void moveto(double x, double y, bool is_open);
- virtual void lineto(double x, double y);
- virtual void quadto(double x1, double y1, double x2, double y2);
- virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3);
+ virtual void moveto(double x, double y);
+ virtual void lineto(double x, double y, bool close_last);
+ virtual void quadto(double x1, double y1, double x2, double y2, bool close_last);
+ virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last);
private:
SPCurve &_curve;
@@ -47,10 +47,10 @@ class ConverterPath : public ConverterBase {
public:
ConverterPath(Geom::Path &path);
- virtual void moveto(double x, double y, bool is_open);
- virtual void lineto(double x, double y);
- virtual void quadto(double x1, double y1, double x2, double y2);
- virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3);
+ virtual void moveto(double x, double y);
+ virtual void lineto(double x, double y, bool close_last);
+ virtual void quadto(double x1, double y1, double x2, double y2, bool close_last);
+ virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last);
private:
Geom::Path &_path;
diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp
index 46e53a0da..0ac2815bf 100644
--- a/src/live_effects/spiro.cpp
+++ b/src/live_effects/spiro.cpp
@@ -847,13 +847,13 @@ solve_spiro(spiro_seg *s, const int nseg)
static void
spiro_seg_to_otherpath(const double ks[4],
double x0, double y0, double x1, double y1,
- ConverterBase &bc, int depth)
+ ConverterBase &bc, int depth, bool close_last)
{
double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) +
fabs((1./48) * ks[3]);
if (!(bend > 1e-8)) {
- bc.lineto(x1, y1);
+ bc.lineto(x1, y1, close_last);
} else {
double seg_ch = hypot(x1 - x0, y1 - y0);
double seg_th = atan2(y1 - y0, x1 - x0);
@@ -876,7 +876,7 @@ spiro_seg_to_otherpath(const double ks[4],
vl = (scale * (1./3)) * sin(th_even - th_odd);
ur = (scale * (1./3)) * cos(th_even + th_odd);
vr = (scale * (1./3)) * sin(th_even + th_odd);
- bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
+ bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1, close_last);
} else {
/* subdivide */
double ksub[4];
@@ -895,11 +895,11 @@ spiro_seg_to_otherpath(const double ks[4],
integrate_spiro(ksub, xysub);
xmid = x0 + cth * xysub[0] - sth * xysub[1];
ymid = y0 + cth * xysub[1] + sth * xysub[0];
- spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
+ spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1, false);
ksub[0] += .25 * ks[1] + (1./384) * ks[3];
ksub[1] += .125 * ks[2];
ksub[2] += (1./16) * ks[3];
- spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
+ spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1, close_last);
}
}
}
@@ -933,9 +933,10 @@ spiro_to_otherpath(const spiro_seg *s, int n, ConverterBase &bc)
double y1 = s[i + 1].y;
if (i == 0) {
- bc.moveto(x0, y0, s[0].ty == '{');
+ bc.moveto(x0, y0);
}
- spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0);
+ // on the last segment, set the 'close_last' flag if path is closed
+ spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0, (nsegs == n) && (i == n - 1));
}
}