summaryrefslogtreecommitdiffstats
path: root/src/live_effects/lpe-bendpath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/live_effects/lpe-bendpath.cpp')
-rw-r--r--src/live_effects/lpe-bendpath.cpp90
1 files changed, 89 insertions, 1 deletions
diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp
index 33171b184..874e23c4c 100644
--- a/src/live_effects/lpe-bendpath.cpp
+++ b/src/live_effects/lpe-bendpath.cpp
@@ -20,7 +20,13 @@
#include <2geom/d2.h>
#include <2geom/piecewise.h>
+#include "knot-holder-entity.h"
+#include "knotholder.h"
+
+#include <glibmm/i18n.h>
+
#include <algorithm>
+
using std::vector;
@@ -48,10 +54,21 @@ first) but I think we can first forget about them.
namespace Inkscape {
namespace LivePathEffect {
+Geom::PathVector bp_helper_path;
+namespace BeP {
+class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity {
+ public:
+ KnotHolderEntityWidthBendPath(LPEBendPath * effect) : LPEKnotHolderEntity(effect) {}
+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+ virtual Geom::Point knot_get() const;
+ };
+} // BeP
+
LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"),
- prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1),
+ original_height(0.0),
+ prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0),
scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false),
vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false)
{
@@ -63,6 +80,7 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) :
prop_scale.param_set_digits(3);
prop_scale.param_set_increments(0.01, 0.10);
+ _provides_knotholder_entities = true;
concatenate_before_pwd2 = true;
}
@@ -76,7 +94,9 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem)
{
// get the item bounding box
original_bbox(lpeitem);
+ original_height = boundingbox_Y.max() - boundingbox_Y.min();
SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
+
item->apply_to_clippath(item);
item->apply_to_mask(item);
}
@@ -148,7 +168,75 @@ LPEBendPath::resetDefaults(SPItem const* item)
bend_path.set_new_value( path.toPwSb(), true );
}
+void
+LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
+{
+ hp_vec.push_back(bp_helper_path);
+}
+
+void
+LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
+{
+ KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this);
+ e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE);
+ knotholder->add(e);
+}
+
+namespace BeP {
+void
+KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state)
+{
+ LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect);
+
+ Geom::Point const s = snap_knot_position(p, state);
+ Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0));
+ Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0));
+ Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0));
+ Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0));
+ Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve);
+ Geom::Ray ray(ptA, B);
+ if (cubic) {
+ ray.setPoints(ptA, (*cubic)[1]);
+ }
+ ray.setAngle(ray.angle() + Geom::deg_to_rad(90));
+ Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse();
+ Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos);
+ if(nearest_to_ray == 0){
+ lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0));
+ } else {
+ lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0));
+ }
+
+ sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
+}
+
+Geom::Point
+KnotHolderEntityWidthBendPath::knot_get() const
+{
+ LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect);
+
+ Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0));
+ Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0));
+ Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0));
+ Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0));
+ Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve);
+ Geom::Ray ray(ptA, B);
+ if (cubic) {
+ ray.setPoints(ptA,(*cubic)[1]);
+ }
+ ray.setAngle(ray.angle() + Geom::deg_to_rad(90));
+ Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA;
+
+ bp_helper_path.clear();
+ Geom::Path hp(result_point);
+ hp.appendNew<Geom::LineSegment>(ptA);
+ bp_helper_path.push_back(hp);
+ hp.clear();
+
+ return result_point;
+}
+} // namespace BeP
} // namespace LivePathEffect
} /* namespace Inkscape */