From af1bbe5ddd52aef9e74a778006b01b3a0e249e5d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 Oct 2015 12:11:48 +0200 Subject: Fix position node splited Added parameter to Symm move nodes, Todo:Get better english strings (bzr r14407) --- src/live_effects/lpe-roughen.cpp | 125 +++++++++++++++++++++++++++++++++------ src/live_effects/lpe-roughen.h | 7 ++- 2 files changed, 111 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 33ffd96d6..108b34a26 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -49,8 +49,10 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "global_randomize", &wr, this, 1.), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), - shift_node_handles(_("Shift node handles"), _("Shift node handles"), - "shift_node_handles", &wr, this, true) + shift_handles(_("Shift node handles"), _("Shift node handles"), + "shift_handles", &wr, this, true), + shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), + "shift_handles_sym", &wr, this, false) { registerParameter(&method); registerParameter(&max_segment_size); @@ -59,7 +61,8 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&displace_y); registerParameter(&global_randomize); registerParameter(&shift_nodes); - registerParameter(&shift_node_handles); + registerParameter(&shift_handles); + registerParameter(&shift_handles_sym); displace_x.param_set_range(0., Geom::infinity()); displace_y.param_set_range(0., Geom::infinity()); global_randomize.param_set_range(0., Geom::infinity()); @@ -170,6 +173,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); + Geom::Point prev(0, 0); if (path_it->closed()) { const Geom::Curve &closingline = path_it->back_closed(); @@ -212,18 +216,26 @@ void LPERoughen::doEffect(SPCurve *curve) } else { splits = ceil(length / max_segment_size); } - for (unsigned int t = splits; t >= 1; t--) { - if (t == 1 && splits != 1) { + Geom::Curve const * original = nCurve->last_segment()->duplicate() ; + for (unsigned int t = 1; t <= splits; t++) { + if(t == splits && splits != 1){ continue; } - const SPCurve *tmp; + SPCurve const * tmp; if (splits == 1) { tmp = jitter(nCurve->last_segment()); } else { - tmp = addNodesAndJitter(nCurve->last_segment(), 1. / t); + bool last = false; + if(t == splits-1){ + last = true; + } + double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment()); + tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last); } if (nCurve->get_segment_count() > 1) { - nCurve->backspace(); + if(t!= splits){ + nCurve->backspace(); + } nCurve->append_continuous(tmp, 0.001); } else { nCurve = tmp->copy(); @@ -237,6 +249,27 @@ void LPERoughen::doEffect(SPCurve *curve) first = false; } if (path_it->closed()) { + if(shift_handles_sym && curve_it2 == curve_endit){ + SPCurve *out = new SPCurve(); + nCurve = nCurve->create_reverse(); + Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); + Geom::CubicBezier const *cubic = dynamic_cast(nCurve->last_segment()); + Geom::Point oposite = nCurve->first_segment()->initialPoint(); + if(cubic_start){ + Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]); + double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]); + oposite = Geom::Point::polar(ray.angle(),dist) + (*cubic_start)[0]; + } + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1], oposite, (*cubic)[3]); + } else { + out->moveto(nCurve->last_segment()->initialPoint()); + out->curveto(nCurve->last_segment()->initialPoint(), oposite, nCurve->last_segment()->finalPoint()); + } + nCurve->backspace(); + nCurve->append_continuous(out, 0.001); + } nCurve->closepath_current(); } curve->append(nCurve, false); @@ -245,7 +278,7 @@ void LPERoughen::doEffect(SPCurve *curve) } } -SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t) +SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); @@ -259,38 +292,94 @@ SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t) point3 = randomize(); point_b3 = randomize(); } - if (shift_node_handles) { + if (shift_handles && !shift_handles_sym) { point1 = randomize(); point2 = randomize(); point_b1 = randomize(); point_b2 = randomize(); - } else { + } else if(shift_handles_sym) { + Geom::Ray ray(prev,A->initialPoint()); + double dist = Geom::distance(prev, A->initialPoint()); + point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); + if(prev==Geom::Point(0,0)){ + point1 = A->pointAt(t / 3) + randomize(); + } + point2 = A->pointAt((t / 3) * 2) + randomize(); + Geom::Ray ray2(point2, point3); + double dist2 = Geom::distance(point2, point3); + point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; + point1 = point1 - A->pointAt(t / 3); + point2 = point2 - A->pointAt((t / 3) * 2); + point_b1 = randomize(); + point_b2 = randomize(); + }else { point2 = point3; point_b1 = point3; point_b2 = point_b3; } - if (cubic) { + if(shift_handles_sym && cubic) { + std::pair div = cubic->subdivide(t); + std::vector seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + out->moveto(seg1[0]); + Geom::Ray ray(prev,A->initialPoint()); + double dist = Geom::distance(seg1[1], A->initialPoint()); + point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); + point2 = seg1[2] + point2; + point3 = seg1[3] + point3; + if(prev==Geom::Point(0,0)){ + point1 = seg1[1] + randomize(); + } + out->curveto(point1, point2, point3); + + Geom::Ray ray2(point2, point3); + double dist2 = Geom::distance(seg2[1], point3); + point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; + point_b2 = seg2[2]; + out->curveto(point_b1, point_b2, seg2[3]); + } else if(shift_handles_sym && !cubic) { + out->moveto(A->initialPoint()); + Geom::Ray ray(prev,A->initialPoint()); + double dist = Geom::distance(A->pointAt(t / 3) + randomize(), A->initialPoint()); + point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); + point2 = A->pointAt((t / 3) * 2) + point2; + point3 = A->pointAt(t) + point3; + if(prev==Geom::Point(0,0)){ + point1 = A->pointAt(t / 3) + randomize(); + } + out->curveto(point1, point2, point3); + Geom::Ray ray2(point2, point3); + double dist2 = Geom::distance(A->pointAt(t + ((t / 3) * 2)) + point_b2, point3); + point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; + point_b2 = A->pointAt(t + ((t / 3) * 2)) + point_b2; + out->curveto(point_b1, point_b2, A->finalPoint()); + } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3); out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]); - } else if (shift_node_handles) { + } else if (shift_handles) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2, A->pointAt(t) + point3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)), - A->finalPoint()); + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)) + point_b2, + A->finalPoint()); } else { out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point3); out->lineto(A->finalPoint()); } + if(last){ + prev = point_b2; + } else { + prev = point2; + } return out; } -SPCurve *LPERoughen::jitter(const Geom::Curve *A) +SPCurve *LPERoughen::jitter(Geom::Curve const * A) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); @@ -300,7 +389,7 @@ SPCurve *LPERoughen::jitter(const Geom::Curve *A) if (shift_nodes) { point3 = randomize(); } - if (shift_node_handles) { + if (shift_handles) { point1 = randomize(); point2 = randomize(); } else { @@ -309,7 +398,7 @@ SPCurve *LPERoughen::jitter(const Geom::Curve *A) if (cubic) { out->moveto((*cubic)[0]); out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3); - } else if (shift_node_handles) { + } else if (shift_handles) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2, A->finalPoint() + point3); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 2b285cd40..8241cedca 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -38,8 +38,8 @@ public: virtual double sign(double randNumber); virtual Geom::Point randomize(); virtual void doBeforeEffect(SPLPEItem const * lpeitem); - virtual SPCurve *addNodesAndJitter(const Geom::Curve *A, double t); - virtual SPCurve *jitter(const Geom::Curve *A); + virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last); + virtual SPCurve *jitter(Geom::Curve const * A); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -51,7 +51,8 @@ private: RandomParam displace_y; RandomParam global_randomize; BoolParam shift_nodes; - BoolParam shift_node_handles; + BoolParam shift_handles; + BoolParam shift_handles_sym; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); -- cgit v1.2.3 From f886fd682e7e4ea2622fbb523dc3a14ba75569a3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 Oct 2015 22:09:54 +0200 Subject: Added a parameter to roughen LPE to allow fixed displacement of points (bzr r14408) --- src/live_effects/lpe-roughen.cpp | 235 +++++++++++++++++++++------------------ src/live_effects/lpe-roughen.h | 5 +- 2 files changed, 127 insertions(+), 113 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 108b34a26..6f24c288d 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -52,7 +52,9 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) shift_handles(_("Shift node handles"), _("Shift node handles"), "shift_handles", &wr, this, true), shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), - "shift_handles_sym", &wr, this, false) + "shift_handles_sym", &wr, this, false), + fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), + "fixed_displacement", &wr, this, false) { registerParameter(&method); registerParameter(&max_segment_size); @@ -63,6 +65,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&shift_nodes); registerParameter(&shift_handles); registerParameter(&shift_handles_sym); + registerParameter(&fixed_displacement); displace_x.param_set_range(0., Geom::infinity()); displace_y.param_set_range(0., Geom::infinity()); global_randomize.param_set_range(0., Geom::infinity()); @@ -150,12 +153,15 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize() +Geom::Point LPERoughen::randomize(double max_lenght) { double displace_x_parsed = displace_x * global_randomize; double displace_y_parsed = displace_y * global_randomize; - Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); + if( fixed_displacement ){ + Geom::Ray ray(Geom::Point(0,0),output); + output = Geom::Point::polar(ray.angle(), max_lenght); + } return output; } @@ -181,33 +187,24 @@ void LPERoughen::doEffect(SPCurve *curve) curve_endit = path_it->end_open(); } } - Geom::Point initialMove(0, 0); - if (shift_nodes) { - initialMove = randomize(); - } - Geom::Point initialPoint = curve_it1->initialPoint() + initialMove; - nCurve->moveto(initialPoint); + nCurve->moveto(curve_it1->initialPoint()); Geom::Point point0(0, 0); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); - bool first = true; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; point0 = curve_it1->initialPoint(); - point1 = curve_it1->initialPoint(); - point2 = curve_it1->finalPoint(); - point3 = curve_it1->finalPoint(); + point_a1 = curve_it1->initialPoint(); + point_a2 = curve_it1->finalPoint(); + point_a3 = curve_it1->finalPoint(); cubic = dynamic_cast(&*curve_it1); if (cubic) { - point1 = (*cubic)[1]; - if (shift_nodes && first) { - point1 = (*cubic)[1] + initialMove; - } - point2 = (*cubic)[2]; - nCurve->curveto(point1, point2, point3); + point_a1 = (*cubic)[1]; + point_a2 = (*cubic)[2]; + nCurve->curveto(point_a1, point_a2, point_a3); } else { - nCurve->lineto(point3); + nCurve->lineto(point_a3); } double length = curve_it1->length(0.001); std::size_t splits = 0; @@ -223,7 +220,7 @@ void LPERoughen::doEffect(SPCurve *curve) } SPCurve const * tmp; if (splits == 1) { - tmp = jitter(nCurve->last_segment()); + tmp = jitter(nCurve->last_segment(), prev); } else { bool last = false; if(t == splits-1){ @@ -233,9 +230,7 @@ void LPERoughen::doEffect(SPCurve *curve) tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last); } if (nCurve->get_segment_count() > 1) { - if(t!= splits){ - nCurve->backspace(); - } + nCurve->backspace(); nCurve->append_continuous(tmp, 0.001); } else { nCurve = tmp->copy(); @@ -246,7 +241,6 @@ void LPERoughen::doEffect(SPCurve *curve) if(curve_it2 != curve_endit) { ++curve_it2; } - first = false; } if (path_it->closed()) { if(shift_handles_sym && curve_it2 == curve_endit){ @@ -254,7 +248,7 @@ void LPERoughen::doEffect(SPCurve *curve) nCurve = nCurve->create_reverse(); Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); Geom::CubicBezier const *cubic = dynamic_cast(nCurve->last_segment()); - Geom::Point oposite = nCurve->first_segment()->initialPoint(); + Geom::Point oposite = nCurve->first_segment()->pointAt(1.0/3.0); if(cubic_start){ Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]); double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]); @@ -269,7 +263,9 @@ void LPERoughen::doEffect(SPCurve *curve) } nCurve->backspace(); nCurve->append_continuous(out, 0.001); + nCurve = nCurve->create_reverse(); } + nCurve->move_endpoints(nCurve->last_segment()->finalPoint(), nCurve->last_segment()->finalPoint()); nCurve->closepath_current(); } curve->append(nCurve, false); @@ -282,129 +278,146 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); + double max_lenght = Geom::distance(A->initialPoint(),A->pointAt(t)) / 3.0; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); Geom::Point point_b1(0, 0); Geom::Point point_b2(0, 0); Geom::Point point_b3(0, 0); if (shift_nodes) { - point3 = randomize(); - point_b3 = randomize(); + point_a3 = randomize(max_lenght); + if(last){ + point_b3 = randomize(max_lenght); + } } - if (shift_handles && !shift_handles_sym) { - point1 = randomize(); - point2 = randomize(); - point_b1 = randomize(); - point_b2 = randomize(); - } else if(shift_handles_sym) { - Geom::Ray ray(prev,A->initialPoint()); - double dist = Geom::distance(prev, A->initialPoint()); - point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); - if(prev==Geom::Point(0,0)){ - point1 = A->pointAt(t / 3) + randomize(); + if (shift_handles || shift_handles_sym) { + point_a1 = randomize(max_lenght); + point_a2 = randomize(max_lenght); + point_b1 = randomize(max_lenght); + if(last){ + point_b2 = randomize(max_lenght); + } + } else { + point_a2 = point_a3; + point_b1 = point_a3; + if(last){ + point_b2 = point_b3; } - point2 = A->pointAt((t / 3) * 2) + randomize(); - Geom::Ray ray2(point2, point3); - double dist2 = Geom::distance(point2, point3); - point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; - point1 = point1 - A->pointAt(t / 3); - point2 = point2 - A->pointAt((t / 3) * 2); - point_b1 = randomize(); - point_b2 = randomize(); - }else { - point2 = point3; - point_b1 = point3; - point_b2 = point_b3; } if(shift_handles_sym && cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); - out->moveto(seg1[0]); Geom::Ray ray(prev,A->initialPoint()); - double dist = Geom::distance(seg1[1], A->initialPoint()); - point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); - point2 = seg1[2] + point2; - point3 = seg1[3] + point3; - if(prev==Geom::Point(0,0)){ - point1 = seg1[1] + randomize(); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = randomize(max_lenght); + } + if(last){ + prev = A->pointAt(1 - (t / 3)) + point_b2; + } else { + point_b3 = Geom::Point(0,0); + point_b2 = Geom::Point(0,0); + } + Geom::Ray ray2(seg2[1] + point_b1, seg1[3] + point_a3); + point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + if(!last){ + prev = seg1[3] + point_a3 + point_a2; + } + out->moveto(seg1[0]); + out->curveto(seg1[0] + point_a1, seg1[3] + point_a3 + point_a2, seg1[3] + point_a3); + if(last){ + out->curveto(seg2[1] + point_b1, A->pointAt(1 - (t / 3)) + point_b2, seg2[3] + point_b3); + } else { + out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); } - out->curveto(point1, point2, point3); - - Geom::Ray ray2(point2, point3); - double dist2 = Geom::distance(seg2[1], point3); - point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; - point_b2 = seg2[2]; - out->curveto(point_b1, point_b2, seg2[3]); } else if(shift_handles_sym && !cubic) { - out->moveto(A->initialPoint()); Geom::Ray ray(prev,A->initialPoint()); - double dist = Geom::distance(A->pointAt(t / 3) + randomize(), A->initialPoint()); - point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint(); - point2 = A->pointAt((t / 3) * 2) + point2; - point3 = A->pointAt(t) + point3; + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ - point1 = A->pointAt(t / 3) + randomize(); + point_a1 = randomize(max_lenght); + } + if(last){ + prev = A->pointAt(1 - (t / 3)) + point_b2; + } else { + point_b3 = Geom::Point(0,0); + point_b2 = Geom::Point(0,0); + } + Geom::Ray ray2(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t) + point_a3); + point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + if(!last){ + prev = A->pointAt((t / 3) * 2) + point_a2; + } + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + if(last){ + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(1 - (t / 3)) + point_b2, A->finalPoint() + point_b3); + } else { + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); } - out->curveto(point1, point2, point3); - Geom::Ray ray2(point2, point3); - double dist2 = Geom::distance(A->pointAt(t + ((t / 3) * 2)) + point_b2, point3); - point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3; - point_b2 = A->pointAt(t + ((t / 3) * 2)) + point_b2; - out->curveto(point_b1, point_b2, A->finalPoint()); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); - out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3); - out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]); + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2, seg1[3] + point_a3); + out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2, - A->pointAt(t) + point3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)) + point_b2, - A->finalPoint()); + out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); } else { out->moveto(A->initialPoint()); - out->lineto(A->pointAt(t) + point3); - out->lineto(A->finalPoint()); - } - if(last){ - prev = point_b2; - } else { - prev = point2; + out->lineto(A->pointAt(t) + point_a3); + out->lineto(A->finalPoint() + point_b3); } return out; } -SPCurve *LPERoughen::jitter(Geom::Curve const * A) +SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast(&*A); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); + double max_lenght = Geom::distance(A->initialPoint(),A->finalPoint()) / 3.0; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); if (shift_nodes) { - point3 = randomize(); + point_a3 = randomize(max_lenght); } - if (shift_handles) { - point1 = randomize(); - point2 = randomize(); - } else { - point2 = point3; + if (shift_handles || shift_handles_sym) { + point_a1 = randomize(max_lenght); + point_a2 = randomize(max_lenght); } - if (cubic) { + if(shift_handles_sym && cubic) { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + prev = (*cubic)[2] + point_a2; + out->moveto((*cubic)[0]); + out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); + } else if(shift_handles_sym && !cubic) { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev==Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + prev = A->pointAt((1.0/3.0) * 2) + point_a2; + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2, A->finalPoint() + point_a3); + } else if (cubic) { out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3); + out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2, - A->finalPoint() + point3); + out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2, + A->finalPoint() + point_a3); } else { out->moveto(A->initialPoint()); - out->lineto(A->finalPoint() + point3); + out->lineto(A->finalPoint() + point_a3); } return out; } diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 8241cedca..e221e95fb 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -36,10 +36,10 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(); + virtual Geom::Point randomize(double max_lenght); virtual void doBeforeEffect(SPLPEItem const * lpeitem); virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last); - virtual SPCurve *jitter(Geom::Curve const * A); + virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -53,6 +53,7 @@ private: BoolParam shift_nodes; BoolParam shift_handles; BoolParam shift_handles_sym; + BoolParam fixed_displacement; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); -- cgit v1.2.3 From bdf7f8acb13e3c1920307674e3fea3cbca8ba12e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 14 Oct 2015 13:20:09 +0200 Subject: Fix from Johan to prevent referencing null C++ pointer. Found via Clang scan build. (bzr r14409) --- src/widgets/gradient-vector.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 259d4c9af..8e92f589a 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -842,7 +842,8 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s GtkWidget *vb, *w, *f; - g_return_val_if_fail(!gradient || SP_IS_GRADIENT(gradient), NULL); + g_return_val_if_fail(gradient != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(gradient), NULL); #if GTK_CHECK_VERSION(3,0,0) vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, PAD); -- cgit v1.2.3 From d6926d4ffcd9fdf0c1e69fb3bf9397eac0f54f81 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 14 Oct 2015 20:42:56 +0200 Subject: improved results of roughen LPE (bzr r14410) --- src/live_effects/lpe-roughen.cpp | 44 ++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 6f24c288d..dec3f955f 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -314,23 +314,19 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - if(last){ - prev = A->pointAt(1 - (t / 3)) + point_b2; - } else { - point_b3 = Geom::Point(0,0); - point_b2 = Geom::Point(0,0); - } - Geom::Ray ray2(seg2[1] + point_b1, seg1[3] + point_a3); - point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + ray.setPoints(seg2[1] + point_a3 + point_b1, seg1[3] + point_a3); + point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(!last){ prev = seg1[3] + point_a3 + point_a2; + } else { + prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; } out->moveto(seg1[0]); - out->curveto(seg1[0] + point_a1, seg1[3] + point_a3 + point_a2, seg1[3] + point_a3); + out->curveto(seg1[0] + point_a1, seg1[2] + point_a3 + point_a2, seg1[3] + point_a3); if(last){ - out->curveto(seg2[1] + point_b1, A->pointAt(1 - (t / 3)) + point_b2, seg2[3] + point_b3); + out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); } else { - out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); } } else if(shift_handles_sym && !cubic) { Geom::Ray ray(prev,A->initialPoint()); @@ -338,35 +334,31 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev==Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - if(last){ - prev = A->pointAt(1 - (t / 3)) + point_b2; - } else { - point_b3 = Geom::Point(0,0); - point_b2 = Geom::Point(0,0); - } - Geom::Ray ray2(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t) + point_a3); - point_a2 = Geom::Point::polar(ray2.angle(), max_lenght); + ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); + point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(!last){ prev = A->pointAt((t / 3) * 2) + point_a2; + } else { + prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; } out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->initialPoint() + point_a1, A->pointAt((t / 3) * 2) + point_a3 + point_a2, A->pointAt(t) + point_a3); if(last){ - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(1 - (t / 3)) + point_b2, A->finalPoint() + point_b3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else { - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); - out->curveto(seg1[1] + point_a1, seg1[2] + point_a2, seg1[3] + point_a3); - out->curveto(seg2[1] + point_b1, seg2[2] + point_b2, seg2[3] + point_b3); + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2, A->pointAt(t) + point_a3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2, A->finalPoint() + point_b3); + out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2 + point_a3, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else { out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point_a3); -- cgit v1.2.3 From e49ce373b61fba07422c156090b0ee7553cde18f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Wed, 14 Oct 2015 21:47:34 +0200 Subject: Fix snapping while rotating a selection Fixed bugs: - https://launchpad.net/bugs/1479167 (bzr r14411) --- src/2geom/path-sink.cpp | 4 ++-- src/object-snapper.cpp | 43 ++++++------------------------------------- src/pure-transform.cpp | 2 +- 3 files changed, 9 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/2geom/path-sink.cpp b/src/2geom/path-sink.cpp index 3b8d407f8..77301b716 100644 --- a/src/2geom/path-sink.cpp +++ b/src/2geom/path-sink.cpp @@ -73,8 +73,8 @@ void PathSink::feed(Rect const &r) { void PathSink::feed(Circle const &e) { Coord r = e.radius(); Point c = e.center(); - Point a = c + Point(0, c[Y] + r); - Point b = c + Point(0, c[Y] - r); + Point a = c + Point(0, +r); + Point b = c + Point(0, -r); moveTo(a); arcTo(r, r, 0, false, false, b); diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 634d56aa6..7302f9de6 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -637,7 +637,6 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr, constraint_line.appendNew(p_max_on_cl); constraint_path.push_back(constraint_line); } - // Length of constraint_path will always be one bool strict_snapping = _snapmanager->snapprefs.getStrictSnapping(); @@ -646,45 +645,15 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(IntermSnapResults &isr, for (std::vector::const_iterator k = _paths_to_snap_to->begin(); k != _paths_to_snap_to->end(); ++k) { if (k->path_vector && _allowSourceToSnapToTarget(p.getSourceType(), (*k).target_type, strict_snapping)) { // Do the intersection math - Geom::CrossingSet cs = Geom::crossings(constraint_path, *(k->path_vector)); - // Store the results as intersection points - unsigned int index = 0; - for (Geom::CrossingSet::const_iterator i = cs.begin(); i != cs.end(); ++i) { - if (index >= constraint_path.size()) { - break; - } - // Reconstruct and store the points of intersection - for (Geom::Crossings::const_iterator m = (*i).begin(); m != (*i).end(); ++m) { - intersections.push_back(constraint_path[index].pointAt((*m).ta)); - } - index++; - } - - //Geom::crossings will not consider the closing segment apparently, so we'll handle that separately here - //TODO: This should have been fixed in rev. #9859, which makes this workaround obsolete - for(Geom::PathVector::iterator it_pv = k->path_vector->begin(); it_pv != k->path_vector->end(); ++it_pv) { - if (it_pv->closed()) { - // Get the closing linesegment and convert it to a path - Geom::Path cls; - cls.close(false); - cls.append(it_pv->back_closed()); - // Intersect that closing path with the constrained path - Geom::Crossings cs = Geom::crossings(constraint_path.front(), cls); - // Reconstruct and store the points of intersection - index = 0; // assuming the constraint path vector has only one path - for (Geom::Crossings::const_iterator m = cs.begin(); m != cs.end(); ++m) { - intersections.push_back(constraint_path[index].pointAt((*m).ta)); - } - } - } + std::vector inters = constraint_path.intersect(*(k->path_vector)); - // Convert the collected points of intersection to snapped points - for (std::vector::iterator p_inters = intersections.begin(); p_inters != intersections.end(); ++p_inters) { + // Convert the collected intersections to snapped points + for (std::vector::const_iterator i = inters.begin(); i != inters.end(); ++i) { // Convert to desktop coordinates - (*p_inters) = dt->doc2dt(*p_inters); + Geom::Point p_inters = dt->doc2dt(i->point()); // Construct a snapped point - Geom::Coord dist = Geom::L2(p.getPoint() - *p_inters); - SnappedPoint s = SnappedPoint(*p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, false, k->target_bbox); + Geom::Coord dist = Geom::L2(p.getPoint() - p_inters); + SnappedPoint s = SnappedPoint(p_inters, p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, false, k->target_bbox); // Store the snapped point if (dist <= tolerance) { // If the intersection is within snapping range, then we might snap to it isr.points.push_back(s); diff --git a/src/pure-transform.cpp b/src/pure-transform.cpp index aa89c8a8e..9c7054b9f 100644 --- a/src/pure-transform.cpp +++ b/src/pure-transform.cpp @@ -63,7 +63,7 @@ void PureTransform::snap(::SnapManager *sm, std::vector todo(owner->hrefList); todo.push_front(owner->parent); while(!todo.empty()){ -- cgit v1.2.3 From b39fc82af6e1320d3c2b301a1639965b04f05fd9 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 15 Oct 2015 01:13:10 +0200 Subject: clang-format (bzr r14413) --- src/uri-references.cpp | 159 +++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 0aae9b39d..b6ccdbf5f 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -26,74 +26,91 @@ namespace Inkscape { URIReference::URIReference(SPObject *owner) - : _owner(owner), _owner_document(NULL), _obj(NULL), _uri(NULL) + : _owner(owner) + , _owner_document(NULL) + , _obj(NULL) + , _uri(NULL) { g_assert(_owner != NULL); /* FIXME !!! attach to owner's destroy signal to clean up in case */ } URIReference::URIReference(SPDocument *owner_document) - : _owner(NULL), _owner_document(owner_document), _obj(NULL), _uri(NULL) + : _owner(NULL) + , _owner_document(owner_document) + , _obj(NULL) + , _uri(NULL) { g_assert(_owner_document != NULL); } -URIReference::~URIReference() -{ - detach(); -} +URIReference::~URIReference() { detach(); } /* * The main ideas here are: * (1) "If we are inside a clone, then we can accept if and only if our "original thing" can accept the reference" - * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id, but also its cloned reprs - * (descendants of referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i could not find a better way. + * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id, + *but also its cloned reprs + * (descendants of referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i + *could not find a better way. * FIXME: find a better and safer way to find the "original object" of anyone with the flag ->cloned * - * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed edges are + * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed + *edges are * either parent->child relations , *** or href'ing to href'ed *** relations, stays acyclic. - * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case linear in the number of objects. - * There are no easy objects allowing to do the second proposition, while "hrefList" is a "list of objects href'ing us", so we'll take this. + * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case + *linear in the number of objects. + * There are no easy objects allowing to do the second proposition, while "hrefList" is a "list of objects href'ing us", + *so we'll take this. * Then we keep a set of already visited elements, and do a DFS on this graph. if we find obj, then BOOM. */ -bool URIReference::_acceptObject(SPObject *obj) const { - //we go back following hrefList and parent to find if the object already references ourselves indirectly - std::set done; - SPObject * owner = getOwner(); - if(!owner)return true; - while(owner->cloned){ - std::vector positions; - while(owner->cloned){ - int position=0; - SPObject* c = owner->parent->firstChild(); - while(c != owner && dynamic_cast(c) ){position++;c=c->next;} - positions.push_back(position); - owner=owner->parent; - } - owner = ((SPUse*)owner)->get_original(); - for(int i=positions.size()-2;i>=0;i--)owner=owner->childList(false)[positions[i]]; - } - //once we have the "original" object (hopefully) we look at who is referencing it - if(obj == owner)return false; - std::list todo(owner->hrefList); - todo.push_front(owner->parent); - while(!todo.empty()){ - SPObject* e = todo.front(); - todo.pop_front(); - if(!dynamic_cast(e))continue; - if(done.insert(e).second){ - if(e==obj){return false;} - todo.push_front(e->parent); - todo.insert(todo.begin(),e->hrefList.begin(),e->hrefList.end()); - } - } +bool URIReference::_acceptObject(SPObject *obj) const +{ + // we go back following hrefList and parent to find if the object already references ourselves indirectly + std::set done; + SPObject *owner = getOwner(); + if (!owner) + return true; + while (owner->cloned) { + std::vector positions; + while (owner->cloned) { + int position = 0; + SPObject *c = owner->parent->firstChild(); + while (c != owner && dynamic_cast(c)) { + position++; + c = c->next; + } + positions.push_back(position); + owner = owner->parent; + } + owner = ((SPUse *)owner)->get_original(); + for (int i = positions.size() - 2; i >= 0; i--) + owner = owner->childList(false)[positions[i]]; + } + // once we have the "original" object (hopefully) we look at who is referencing it + if (obj == owner) + return false; + std::list todo(owner->hrefList); + todo.push_front(owner->parent); + while (!todo.empty()) { + SPObject *e = todo.front(); + todo.pop_front(); + if (!dynamic_cast(e)) + continue; + if (done.insert(e).second) { + if (e == obj) { + return false; + } + todo.push_front(e->parent); + todo.insert(todo.begin(), e->hrefList.begin(), e->hrefList.end()); + } + } return true; } - void URIReference::attach(const URI &uri) throw(BadURIException) { SPDocument *document = NULL; @@ -109,32 +126,30 @@ void URIReference::attach(const URI &uri) throw(BadURIException) // PNG and JPG files are allowed (in the case of feImage). gchar *filename = uri.toString(); bool skip = false; - if( g_str_has_suffix( filename, ".jpg" ) || - g_str_has_suffix( filename, ".JPG" ) || - g_str_has_suffix( filename, ".png" ) || - g_str_has_suffix( filename, ".PNG" ) ) { + if (g_str_has_suffix(filename, ".jpg") || g_str_has_suffix(filename, ".JPG") || + g_str_has_suffix(filename, ".png") || g_str_has_suffix(filename, ".PNG")) { skip = true; } - + // The path contains references to separate document files to load. - if(document && uri.getPath() && !skip ) { + if (document && uri.getPath() && !skip) { std::string base = document->getBase() ? document->getBase() : ""; std::string path = uri.getFullPath(base); - if(!path.empty()) { + if (!path.empty()) { document = document->createChildDoc(path); } else { document = NULL; } } - if(!document) { + if (!document) { g_warning("Can't get document for referenced URI: %s", filename); - g_free( filename ); + g_free(filename); return; } - g_free( filename ); + g_free(filename); gchar const *fragment = uri.getFragment(); - if ( !uri.isRelative() || uri.getQuery() || !fragment ) { + if (!uri.isRelative() || uri.getQuery() || !fragment) { throw UnsupportedURIException(); } @@ -149,9 +164,9 @@ void URIReference::attach(const URI &uri) throw(BadURIException) the strlen calculation and validity testing to before strdup, and copying just the id without the "))". -- pjrm */ if (!strncmp(fragment, "xpointer(id(", 12)) { - id = g_strdup(fragment+12); + id = g_strdup(fragment + 12); size_t const len = strlen(id); - if ( len < 3 || strcmp(id+len-2, "))") ) { + if (len < 3 || strcmp(id + len - 2, "))")) { g_free(id); throw MalformedURIException(); } @@ -184,13 +199,14 @@ void URIReference::detach() void URIReference::_setObject(SPObject *obj) { - if ( obj && !_acceptObject(obj) ) { + if (obj && !_acceptObject(obj)) { obj = NULL; } - if ( obj == _obj ) return; + if (obj == _obj) + return; - SPObject *old_obj=_obj; + SPObject *old_obj = _obj; _obj = obj; _release_connection.disconnect(); @@ -211,7 +227,7 @@ void URIReference::_setObject(SPObject *obj) */ void URIReference::_release(SPObject *obj) { - g_assert( _obj == obj ); + g_assert(_obj == obj); _setObject(NULL); } @@ -219,28 +235,27 @@ void URIReference::_release(SPObject *obj) -SPObject* sp_css_uri_reference_resolve( SPDocument *document, const gchar *uri ) +SPObject *sp_css_uri_reference_resolve(SPDocument *document, const gchar *uri) { - SPObject* ref = NULL; + SPObject *ref = NULL; - if ( document && uri && ( strncmp(uri, "url(", 4) == 0 ) ) { - gchar *trimmed = extract_uri( uri ); - if ( trimmed ) { - ref = sp_uri_reference_resolve( document, trimmed ); - g_free( trimmed ); + if (document && uri && (strncmp(uri, "url(", 4) == 0)) { + gchar *trimmed = extract_uri(uri); + if (trimmed) { + ref = sp_uri_reference_resolve(document, trimmed); + g_free(trimmed); } } return ref; } -SPObject * -sp_uri_reference_resolve (SPDocument *document, const gchar *uri) +SPObject *sp_uri_reference_resolve(SPDocument *document, const gchar *uri) { - SPObject* ref = NULL; + SPObject *ref = NULL; - if ( uri && (*uri == '#') ) { - ref = document->getObjectById( uri + 1 ); + if (uri && (*uri == '#')) { + ref = document->getObjectById(uri + 1); } return ref; -- cgit v1.2.3 From b80f68e9585593a78bad9ae34385cbebe780299a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 Oct 2015 13:52:47 +0200 Subject: Add new 'writing-mode' values, remove 'block-progression', fix a few typos. (bzr r14416) --- src/attributes-test.h | 3 ++- src/attributes.cpp | 2 +- src/attributes.h | 2 +- src/libnrtype/Layout-TNG-Input.cpp | 7 ------- src/style-enums.h | 39 +++++++++++++++++++++++++------------- src/style.cpp | 27 ++++++++++++++------------ src/style.h | 8 ++++---- 7 files changed, 49 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/attributes-test.h b/src/attributes-test.h index 411304ec3..e197deedf 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -43,6 +43,7 @@ public: SVG 2: text-decoration-fill, text-decoration-stroke SVG 2: solid-color, solid-opacity SVG 2: Hatches and Meshes + CSS 3: text-orientation CSS 3: font-variant-xxx, font-feature-settings */ struct {char const *attr; bool supported;} const all_attrs[] = { @@ -69,7 +70,6 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"baseProfile", false}, {"bbox", true}, {"bias", true}, - {"block-progression", true}, {"by", true}, {"calcMode", true}, {"cap-height", true}, @@ -334,6 +334,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"widths", true}, {"word-spacing", true}, {"writing-mode", true}, + {"text-orientation", true}, {"x", true}, {"x-height", true}, {"x1", true}, diff --git a/src/attributes.cpp b/src/attributes.cpp index 991834cb2..a237f8861 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -440,8 +440,8 @@ static SPStyleProp const props[] = { /* Text (css3) */ {SP_PROP_DIRECTION, "direction"}, - {SP_PROP_BLOCK_PROGRESSION, "block-progression"}, {SP_PROP_WRITING_MODE, "writing-mode"}, + {SP_PROP_TEXT_ORIENTATION, "text-orientation"}, {SP_PROP_UNICODE_BIDI, "unicode-bidi"}, {SP_PROP_ALIGNMENT_BASELINE, "alignment-baseline"}, {SP_PROP_BASELINE_SHIFT, "baseline-shift"}, diff --git a/src/attributes.h b/src/attributes.h index 47f1388b0..42ec99d8f 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -444,8 +444,8 @@ enum SPAttributeEnum { SP_PROP_TEXT_TRANSFORM, SP_PROP_DIRECTION, - SP_PROP_BLOCK_PROGRESSION, SP_PROP_WRITING_MODE, + SP_PROP_TEXT_ORIENTATION, SP_PROP_UNICODE_BIDI, SP_PROP_ALIGNMENT_BASELINE, SP_PROP_BASELINE_SHIFT, diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index c9cfe81cc..9c2fc5c11 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -172,11 +172,6 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const return medium_font_size * inherit_multiplier; } -static const Layout::EnumConversionItem enum_convert_spstyle_block_progression_to_direction[] = { - {SP_CSS_BLOCK_PROGRESSION_TB, Layout::TOP_TO_BOTTOM}, - {SP_CSS_BLOCK_PROGRESSION_LR, Layout::LEFT_TO_RIGHT}, - {SP_CSS_BLOCK_PROGRESSION_RL, Layout::RIGHT_TO_LEFT}}; - static const Layout::EnumConversionItem enum_convert_spstyle_writing_mode_to_direction[] = { {SP_CSS_WRITING_MODE_LR_TB, Layout::TOP_TO_BOTTOM}, {SP_CSS_WRITING_MODE_RL_TB, Layout::TOP_TO_BOTTOM}, @@ -190,8 +185,6 @@ Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() cons SPStyle const *this_style = style; for ( ; ; ) { - if (this_style->block_progression.set) - return (Layout::Direction)_enum_converter(this_style->block_progression.computed, enum_convert_spstyle_block_progression_to_direction, sizeof(enum_convert_spstyle_block_progression_to_direction)/sizeof(enum_convert_spstyle_block_progression_to_direction[0])); if (this_style->writing_mode.set) return (Layout::Direction)_enum_converter(this_style->writing_mode.computed, enum_convert_spstyle_writing_mode_to_direction, sizeof(enum_convert_spstyle_writing_mode_to_direction)/sizeof(enum_convert_spstyle_writing_mode_to_direction[0])); if (this_style->object == NULL || this_style->object->parent == NULL) break; diff --git a/src/style-enums.h b/src/style-enums.h index dfc99282c..03255b3b1 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -163,12 +163,6 @@ enum SPCSSDirection { SP_CSS_DIRECTION_RTL }; -enum SPCSSBlockProgression { - SP_CSS_BLOCK_PROGRESSION_TB, - SP_CSS_BLOCK_PROGRESSION_RL, - SP_CSS_BLOCK_PROGRESSION_LR -}; - enum SPCSSWritingMode { SP_CSS_WRITING_MODE_LR_TB, SP_CSS_WRITING_MODE_RL_TB, @@ -176,6 +170,16 @@ enum SPCSSWritingMode { SP_CSS_WRITING_MODE_TB_LR }; +// CSS WRITING MODES 3 +enum SPCSSTextOrientation { + SP_CSS_TEXT_ORIENTATION_MIXED, + SP_CSS_TEXT_ORIENTATION_UPRIGHT, + SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT, + SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT, + SP_CSS_TEXT_ORIENTATION_SIDEWAYS, + SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION +}; + enum SPTextAnchor { SP_CSS_TEXT_ANCHOR_START, SP_CSS_TEXT_ANCHOR_MIDDLE, @@ -489,13 +493,6 @@ static SPStyleEnum const enum_direction[] = { {NULL, -1} }; -static SPStyleEnum const enum_block_progression[] = { - {"tb", SP_CSS_BLOCK_PROGRESSION_TB}, - {"rl", SP_CSS_BLOCK_PROGRESSION_RL}, - {"lr", SP_CSS_BLOCK_PROGRESSION_LR}, - {NULL, -1} -}; - static SPStyleEnum const enum_writing_mode[] = { /* Note that using the same enumerator for lr as lr-tb means we write as lr-tb even if the * input file said lr. We prefer writing lr-tb on the grounds that the spec says the initial @@ -504,12 +501,28 @@ static SPStyleEnum const enum_writing_mode[] = { * ECMA scripts may be surprised to find tb-rl in DOM if they set the attribute to rl, so * sharing enumerators for different strings may be a bug (once we support ecma script). */ + // SVG 1.1 Deprecated but still must be supported in SVG 2. {"lr-tb", SP_CSS_WRITING_MODE_LR_TB}, {"rl-tb", SP_CSS_WRITING_MODE_RL_TB}, {"tb-rl", SP_CSS_WRITING_MODE_TB_RL}, {"lr", SP_CSS_WRITING_MODE_LR_TB}, {"rl", SP_CSS_WRITING_MODE_RL_TB}, {"tb", SP_CSS_WRITING_MODE_TB_RL}, + // SVG 2 & CSS 3 Writing Modes + {"horizontal-tb", SP_CSS_WRITING_MODE_LR_TB}, // This is correct, 'direction' distinguishes between 'lr' and 'rl'. + {"vertical-rl", SP_CSS_WRITING_MODE_TB_RL}, + {"vertical-lr", SP_CSS_WRITING_MODE_TB_LR}, + {NULL, -1} +}; + +// CSS WRITING MODES 3 +static SPStyleEnum const enum_text_orientation[] = { + {"mixed", SP_CSS_TEXT_ORIENTATION_MIXED}, // Default + {"upright", SP_CSS_TEXT_ORIENTATION_UPRIGHT}, + {"sideways-right", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_RIGHT}, + {"sideways-left", SP_CSS_TEXT_ORIENTATION_SIDEWAYS_LEFT}, + {"sideways", SP_CSS_TEXT_ORIENTATION_SIDEWAYS}, + {"use-glyph-orientation", SP_CSS_TEXT_ORIENTATION_USE_GLYPH_ORIENTATION}, {NULL, -1} }; diff --git a/src/style.cpp b/src/style.cpp index 0cb5db0a7..369127792 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -136,8 +136,8 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : text_transform( "text-transform", enum_text_transform, SP_CSS_TEXT_TRANSFORM_NONE ), direction( "direction", enum_direction, SP_CSS_DIRECTION_LTR ), - block_progression("block-progression", enum_block_progression, SP_CSS_BLOCK_PROGRESSION_TB), writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ), + text_orientation( "text-orientation",enum_text_orientation,SP_CSS_TEXT_ORIENTATION_MIXED ), baseline_shift(), text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), @@ -318,9 +318,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &word_spacing ); _properties.push_back( &text_transform ); - _properties.push_back( &direction ); - _properties.push_back( &block_progression ); _properties.push_back( &writing_mode ); + _properties.push_back( &direction ); + _properties.push_back( &text_orientation ); _properties.push_back( &baseline_shift ); _properties.push_back( &text_anchor ); _properties.push_back( &white_space ); @@ -413,8 +413,8 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( text_transform.name, reinterpret_cast(&SPStyle::text_transform ) ) ); // _propmap.insert( std::make_pair( direction.name, reinterpret_cast(&SPStyle::direction ) ) ); - // _propmap.insert( std::make_pair( block_progression.name, reinterpret_cast(&SPStyle::block_progression ) ) ); // _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast(&SPStyle::writing_mode ) ) ); + // _propmap.insert( std::make_pair( text_orientation.name, reinterpret_cast(&SPStyle::text_orientation ) ) ); // _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast(&SPStyle::baseline_shift ) ) ); // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast(&SPStyle::text_anchor ) ) ); // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast(&SPStyle::white_space ) ) ); @@ -778,12 +778,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_DIRECTION: direction.readIfUnset( val ); break; - case SP_PROP_BLOCK_PROGRESSION: - block_progression.readIfUnset( val ); - break; case SP_PROP_WRITING_MODE: writing_mode.readIfUnset( val ); break; + case SP_PROP_TEXT_ORIENTATION: + text_orientation.readIfUnset( val ); + break; case SP_PROP_TEXT_ANCHOR: text_anchor.readIfUnset( val ); break; @@ -1689,16 +1689,19 @@ sp_style_unset_property_attrs(SPObject *o) repr->setAttribute("text-anchor", NULL); } if (style->white_space.set) { - repr->setAttribute("white_space", NULL); + repr->setAttribute("white-space", NULL); } if (style->shape_inside.set) { - repr->setAttribute("shape_inside", NULL); + repr->setAttribute("shape-inside", NULL); } if (style->shape_padding.set) { - repr->setAttribute("shape_padding", NULL); + repr->setAttribute("shape-padding", NULL); } if (style->writing_mode.set) { - repr->setAttribute("writing_mode", NULL); + repr->setAttribute("writing-mode", NULL); + } + if (style->text_orientation.set) { + repr->setAttribute("text-orientation", NULL); } if (style->filter.set) { repr->setAttribute("filter", NULL); @@ -1781,8 +1784,8 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "word-spacing", NULL); sp_repr_css_set_property(css, "text-transform", NULL); sp_repr_css_set_property(css, "direction", NULL); - sp_repr_css_set_property(css, "block-progression", NULL); sp_repr_css_set_property(css, "writing-mode", NULL); + sp_repr_css_set_property(css, "text-orientation", NULL); sp_repr_css_set_property(css, "text-anchor", NULL); sp_repr_css_set_property(css, "white-space", NULL); sp_repr_css_set_property(css, "shape-inside", NULL); diff --git a/src/style.h b/src/style.h index 02432d3e7..3948b876c 100644 --- a/src/style.h +++ b/src/style.h @@ -142,12 +142,12 @@ public: SPIEnum text_transform; /* CSS3 Text */ - /** text direction (css3 text 3.2) */ + /** text direction (svg1.1) */ SPIEnum direction; - /** block progression (css3 text 3.2) */ - SPIEnum block_progression; - /** Writing mode (css3 text 3.2 and svg1.1 10.7.2) */ + /** Writing mode (svg1.1 10.7.2, CSS Writing Modes 3) */ SPIEnum writing_mode; + /** Text orientation (CSS Writing Modes 3) */ + SPIEnum text_orientation; /** Baseline shift (svg1.1 10.9.2) */ SPIBaselineShift baseline_shift; -- cgit v1.2.3 From d929999b79640a8b1425a999483d782883035d3b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 Oct 2015 14:14:01 +0200 Subject: Simplify code after removal of 'block-progression'. (bzr r14417) --- src/libnrtype/Layout-TNG-Input.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 9c2fc5c11..77480cebe 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -172,27 +172,24 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const return medium_font_size * inherit_multiplier; } -static const Layout::EnumConversionItem enum_convert_spstyle_writing_mode_to_direction[] = { - {SP_CSS_WRITING_MODE_LR_TB, Layout::TOP_TO_BOTTOM}, - {SP_CSS_WRITING_MODE_RL_TB, Layout::TOP_TO_BOTTOM}, - {SP_CSS_WRITING_MODE_TB_RL, Layout::RIGHT_TO_LEFT}, - {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; - Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() const { - // this function shouldn't be necessary, but since style.cpp doesn't support - // shorthand properties yet, it is. - SPStyle const *this_style = style; + switch( style->writing_mode.computed ) { - for ( ; ; ) { - if (this_style->writing_mode.set) - return (Layout::Direction)_enum_converter(this_style->writing_mode.computed, enum_convert_spstyle_writing_mode_to_direction, sizeof(enum_convert_spstyle_writing_mode_to_direction)/sizeof(enum_convert_spstyle_writing_mode_to_direction[0])); - if (this_style->object == NULL || this_style->object->parent == NULL) break; - this_style = this_style->object->parent->style; - if (this_style == NULL) break; - } + case SP_CSS_WRITING_MODE_LR_TB: + case SP_CSS_WRITING_MODE_RL_TB: return TOP_TO_BOTTOM; + + case SP_CSS_WRITING_MODE_TB_RL: + return RIGHT_TO_LEFT; + + case SP_CSS_WRITING_MODE_TB_LR: + return LEFT_TO_RIGHT; + default: + std::cerr << "Layout::InputTextStream::styleGetBlockProgression: invalid writing mode." << std::endl; + } + return TOP_TO_BOTTOM; } static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction) -- cgit v1.2.3 From f8a67994cf1d608c6f14e7c41497b62f4a402392 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 15 Oct 2015 17:15:00 +0200 Subject: Bug fixes in roughen and added uption to retract handles (bzr r14418) --- src/live_effects/lpe-roughen.cpp | 82 ++++++++++++++++++---------------------- src/live_effects/lpe-roughen.h | 1 + 2 files changed, 38 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index dec3f955f..ed1ddcaf8 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -51,6 +51,8 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) true), shift_handles(_("Shift node handles"), _("Shift node handles"), "shift_handles", &wr, this, true), + retract_handles(_("Retract node handles"), _("Retract node handles"), + "retract_handles", &wr, this, false), shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), "shift_handles_sym", &wr, this, false), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), @@ -64,6 +66,7 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&global_randomize); registerParameter(&shift_nodes); registerParameter(&shift_handles); + registerParameter(&retract_handles); registerParameter(&shift_handles_sym); registerParameter(&fixed_displacement); displace_x.param_set_range(0., Geom::infinity()); @@ -167,8 +170,7 @@ Geom::Point LPERoughen::randomize(double max_lenght) void LPERoughen::doEffect(SPCurve *curve) { - Geom::PathVector const original_pathv = - pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); curve->reset(); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -180,31 +182,14 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); Geom::Point prev(0, 0); - if (path_it->closed()) { - const Geom::Curve &closingline = - path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } nCurve->moveto(curve_it1->initialPoint()); - Geom::Point point0(0, 0); - Geom::Point point_a1(0, 0); - Geom::Point point_a2(0, 0); - Geom::Point point_a3(0, 0); while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; - point0 = curve_it1->initialPoint(); - point_a1 = curve_it1->initialPoint(); - point_a2 = curve_it1->finalPoint(); - point_a3 = curve_it1->finalPoint(); cubic = dynamic_cast(&*curve_it1); if (cubic) { - point_a1 = (*cubic)[1]; - point_a2 = (*cubic)[2]; - nCurve->curveto(point_a1, point_a2, point_a3); + nCurve->curveto((*cubic)[1], (*cubic)[2], curve_it1->finalPoint()); } else { - nCurve->lineto(point_a3); + nCurve->lineto(curve_it1->finalPoint()); } double length = curve_it1->length(0.001); std::size_t splits = 0; @@ -238,12 +223,10 @@ void LPERoughen::doEffect(SPCurve *curve) delete tmp; } ++curve_it1; - if(curve_it2 != curve_endit) { - ++curve_it2; - } + ++curve_it2; } if (path_it->closed()) { - if(shift_handles_sym && curve_it2 == curve_endit){ + if(shift_handles_sym && curve_it1 == curve_endit && !retract_handles){ SPCurve *out = new SPCurve(); nCurve = nCurve->create_reverse(); Geom::CubicBezier const *cubic_start = dynamic_cast(nCurve->first_segment()); @@ -305,7 +288,17 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b2 = point_b3; } } - if(shift_handles_sym && cubic) { + if(retract_handles){ + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + point_a3); + if(cubic && !last){ + std::pair div = cubic->subdivide(t); + std::vector seg2 = div.second.controlPoints(); + out->curveto(seg2[1], seg2[2], seg2[3]); + } else { + out->lineto(A->finalPoint() + point_b3); + } + } else if(shift_handles_sym && cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); @@ -314,15 +307,15 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } - ray.setPoints(seg2[1] + point_a3 + point_b1, seg1[3] + point_a3); + ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); - if(!last){ - prev = seg1[3] + point_a3 + point_a2; - } else { + if(last){ prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; + } else { + prev = seg1[3] + point_a2 + point_a3; } out->moveto(seg1[0]); - out->curveto(seg1[0] + point_a1, seg1[2] + point_a3 + point_a2, seg1[3] + point_a3); + out->curveto(seg1[0] + point_a1, seg1[3] + point_a2 + point_a3, seg1[3] + point_a3); if(last){ out->curveto(seg2[1] + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, seg2[3] + point_b3); } else { @@ -336,18 +329,14 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); - if(!last){ - prev = A->pointAt((t / 3) * 2) + point_a2; - } else { - prev = A->pointAt(1 - (t / 3)) + point_b2 + point_b3; - } - out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt((t / 3) * 2) + point_a3 + point_a2, A->pointAt(t) + point_a3); if(last){ - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(1 - (t / 3)) + point_b2 + point_b3, A->finalPoint() + point_b3); + prev = A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3; } else { - out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); + prev = A->pointAt(t) + point_a3 + point_a2; } + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt(t) + point_a3 + point_a2, A->pointAt(t) + point_a3); + out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); } else if (cubic) { std::pair div = cubic->subdivide(t); std::vector seg1 = div.first.controlPoints(), @@ -382,7 +371,10 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); } - if(shift_handles_sym && cubic) { + if(retract_handles){ + out->moveto(A->initialPoint()); + out->lineto(A->finalPoint() + point_a3); + } else if(shift_handles_sym && cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ @@ -390,7 +382,7 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) } prev = (*cubic)[2] + point_a2; out->moveto((*cubic)[0]); - out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); + out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); } else if(shift_handles_sym && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); @@ -399,13 +391,13 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) } prev = A->pointAt((1.0/3.0) * 2) + point_a2; out->moveto(A->initialPoint()); - out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2, A->finalPoint() + point_a3); + out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); } else if (cubic) { out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2, (*cubic)[3] + point_a3); + out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); } else if (shift_handles) { out->moveto(A->initialPoint()); - out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2, + out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3, A->finalPoint() + point_a3); } else { out->moveto(A->initialPoint()); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index e221e95fb..57a516310 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -52,6 +52,7 @@ private: RandomParam global_randomize; BoolParam shift_nodes; BoolParam shift_handles; + BoolParam retract_handles; BoolParam shift_handles_sym; BoolParam fixed_displacement; -- cgit v1.2.3