summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiam P. White <inkscapebronyat-signgmaildotcom>2014-04-12 04:52:48 +0000
committerLiam P. White <inkscapebronyat-signgmaildotcom>2014-04-12 04:52:48 +0000
commita354238633c206078acc11a60d02382cee572740 (patch)
tree95ff6c23022d538d5f138bf26f5d98e60b5ec031 /src
parentUpdaet to trunk (diff)
downloadinkscape-a354238633c206078acc11a60d02382cee572740.tar.gz
inkscape-a354238633c206078acc11a60d02382cee572740.zip
Wonderful code optimizations
(bzr r13090.1.50)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-taperstroke.cpp153
-rw-r--r--src/live_effects/pathoutlineprovider.cpp79
-rw-r--r--src/live_effects/pathoutlineprovider.h6
3 files changed, 46 insertions, 192 deletions
diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp
index 901abff70..ce07ed962 100644
--- a/src/live_effects/lpe-taperstroke.cpp
+++ b/src/live_effects/lpe-taperstroke.cpp
@@ -180,77 +180,15 @@ void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem)
//actual effect impl here
-Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.05)
+Geom::Path return_at_first_cusp (Geom::Path const & path_in, double /*smooth_tolerance*/ = 0.05)
{
- Geom::Path path_out = Geom::Path();
-
- for (unsigned i = 0; i < path_in.size(); i++) {
- path_out.append(path_in[i]);
- if (path_in.size() == 1)
- break;
-
- //determine order of curve
- int order = Outline::bezierOrder(&path_in[i]);
-
- Geom::Point start_point;
- Geom::Point cross_point = path_in[i].finalPoint();
- Geom::Point end_point;
-
- g_assert(path_in[i].finalPoint() == path_in[i+1].initialPoint());
-
- //can you tell that the following expressions have been shaped by
- //repeated compiler errors? ;)
- switch (order) {
- case 3:
- start_point = (static_cast<const Geom::CubicBezier*>(&path_in[i]))->operator[] (2);
- //major league b***f***ing
- if (are_near(start_point, cross_point, 0.0000001)) {
- start_point = (static_cast<const Geom::CubicBezier*>(&path_in[i]))->operator[] (1);
- }
- break;
- case 2:
- //this never happens
- start_point = (static_cast<const Geom::QuadraticBezier*>(&path_in[i]))->operator[] (1);
- break;
- case 1:
- default:
- start_point = path_in[i].initialPoint();
- }
-
- order = Outline::bezierOrder(&path_in[i+1]);
-
- switch (order) {
- case 3:
- end_point = (static_cast<const Geom::CubicBezier*>(&path_in[i+1]))->operator[] (1);
- if (are_near(end_point, cross_point, 0.0000001)) {
- end_point = (static_cast<const Geom::CubicBezier*>(&path_in[i+1]))->operator[] (2);
- }
- break;
- case 2:
- end_point = (static_cast<const Geom::QuadraticBezier*>(&path_in[i+1]))->operator[] (1);
- break;
- case 1:
- default:
- end_point = path_in[i+1].finalPoint();
- }
-
- //clearly it's collinear if two occupy the same point
- if (are_near(start_point, cross_point, 0.0000001) ||
- are_near(cross_point, end_point, 0.0000001) ||
- are_near(start_point, end_point, 0.0000001) ) {
- g_critical("Holy crap, something went wrong! %s:%d\n", __FILE__, __LINE__);
- }
-
- if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance))
- break;
- }
- return path_out;
+ return Geom::split_at_cusps(path_in)[0];
}
Geom::Piecewise<Geom::D2<Geom::SBasis> > stretch_along(Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in, Geom::Path pattern, double width);
//references to pointers, because magic
-void subdivideCurve(const Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second);
+void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second);
Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
{
@@ -378,34 +316,9 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa
trimmed_start.append(path_in[0] [i]);
}
-
- //this is pretty annoying
- //previously I wrote a function for this but it wasted a lot of time
- //so I optimized it back into here.
- unsigned order = Outline::bezierOrder(curve_start);
- switch (order) {
- case 3: {
- Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_start);
- std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide((attach_start - loc));
- trimmed_start.append(cb_pair.first);
- curve_start = cb_pair.second.duplicate(); //goes out of scope
- break;
- }
- case 2: {
- Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_start);
- std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide((attach_start - loc));
- trimmed_start.append(qb_pair.first);
- curve_start = qb_pair.second.duplicate();
- break;
- }
- case 1: {
- Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_start);
- std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide((attach_start - loc));
- trimmed_start.append(lb_pair.first);
- curve_start = lb_pair.second.duplicate();
- break;
- }
- }
+ Geom::Curve * temp;
+ subdivideCurve(curve_start, attach_start - loc, temp, curve_start);
+ trimmed_start.append(*temp);
//special case: path is one segment long
//special case: what if the two knots occupy the same segment?
@@ -416,31 +329,9 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa
//we have to do some shifting here because the value changed when we reduced the length
//of the previous segment.
- order = Outline::bezierOrder(curve_start);
- switch (order) {
- case 3: {
- Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_start);
- std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide(t);
- trimmed_end.append(cb_pair.second);
- curve_start = cb_pair.first.duplicate();
- break;
- }
- case 2: {
- Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_start);
- std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide(t);
- trimmed_end.append(qb_pair.second);
- curve_start = qb_pair.first.duplicate();
- break;
- }
- case 1: {
- Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_start);
- std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t);
- trimmed_end.append(lb_pair.second);
- curve_start = lb_pair.first.duplicate();
- break;
- }
- }
-
+ subdivideCurve(curve_start, t, curve_start, temp);
+ trimmed_end.append(*temp);
+
for (unsigned j = (size - attach_end) + 1; j < size; j++) {
trimmed_end.append(path_in[0] [j]);
}
@@ -468,30 +359,8 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa
Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end);
- order = Outline::bezierOrder(curve_end);
- switch (order) {
- case 3: {
- Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_end);
- std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide(t);
- trimmed_end.append(cb_pair.second);
- curve_end = cb_pair.first.duplicate();
- break;
- }
- case 2: {
- Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_end);
- std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide(t);
- trimmed_end.append(qb_pair.second);
- curve_end = qb_pair.first.duplicate();
- break;
- }
- case 1: {
- Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_end);
- std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t);
- trimmed_end.append(lb_pair.second);
- curve_end = lb_pair.first.duplicate();
- break;
- }
- }
+ subdivideCurve(curve_end, t, curve_end, temp);
+ trimmed_end.append(*temp);
for (unsigned j = (size - attach_end) + 1; j < size; j++) {
trimmed_end.append(path_in[0] [j]);
diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp
index a696728d6..5a95da75d 100644
--- a/src/live_effects/pathoutlineprovider.cpp
+++ b/src/live_effects/pathoutlineprovider.cpp
@@ -9,6 +9,7 @@
#include <2geom/shape.h>
#include <2geom/transforms.h>
#include <2geom/path-sink.h>
+#include "helper/geom-nodetype.h"
#include <svg/svg.h>
namespace Geom {
@@ -99,21 +100,25 @@ static Circle touching_circle( D2<SBasis> const &curve, double t, double tol=0.0
return Geom::Circle(center, fabs(radius));
}
-static std::vector<Geom::Path> split_at_cusps(const Geom::Path& in)
+std::vector<Geom::Path> split_at_cusps(const Geom::Path& in)
{
- Geom::PathVector out = Geom::PathVector();
- Geom::Path temp = Geom::Path();
-
- for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) {
- temp = Geom::Path();
- temp.append(in[path_descr]);
+ PathVector out = PathVector();
+ Path temp = Path();
+
+ for (unsigned i = 0; i < in.size(); i++) {
+ temp.append(in[i]);
+ if ( get_nodetype(in[i], in[i + 1]) != Geom::NODE_SMOOTH ) {
+ out.push_back(temp);
+ temp = Path();
+ }
+ }
+ if (temp.size() > 0) {
out.push_back(temp);
}
-
return out;
}
-static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in)
+Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in)
{
std::vector<Geom::Point> temp;
sbasis_to_bezier(temp, sbasis_in, 4);
@@ -140,13 +145,9 @@ typedef Geom::Piecewise<D2SB> PWD2;
unsigned bezierOrder (const Geom::Curve* curve_in)
{
using namespace Geom;
- //cast it
- const CubicBezier *cbc = dynamic_cast<const CubicBezier*>(curve_in);
- if (cbc) return 3;
- const QuadraticBezier * qbc = dynamic_cast<const QuadraticBezier*>(curve_in);
- if (qbc) return 2;
- const BezierCurveN<1U> * lbc = dynamic_cast<const BezierCurveN<1U> *>(curve_in);
- if (lbc) return 1;
+ if ( const BezierCurve* bz = dynamic_cast<const BezierCurve*>(curve_in) ) {
+ return bz->order();
+ }
return 0;
}
@@ -154,8 +155,6 @@ unsigned bezierOrder (const Geom::Curve* curve_in)
//is >180 clockwise, otherwise false.
bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2)
{
- unsigned order = bezierOrder(&cbc1);
-
Geom::Point start_point;
Geom::Point cross_point = cbc1.finalPoint();
Geom::Point end_point;
@@ -167,38 +166,18 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2)
"By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__);
return false;
}
- switch (order) {
- case 3:
- start_point = (static_cast<const Geom::CubicBezier*>(&cbc1))->operator[] (2);
- //major league b***f***ing
- if (are_near(start_point, cross_point, 0.0000001)) {
- start_point = (static_cast<const Geom::CubicBezier*>(&cbc1))->operator[] (1);
- }
- break;
- case 2:
- //this never happens
- start_point = (static_cast<const Geom::QuadraticBezier*>(&cbc1))->operator[] (1);
- break;
- case 1:
- default:
- start_point = cbc1.initialPoint();
+
+ //let's try:
+ Geom::CubicBezier cubicBezier = Geom::sbasis_to_cubicbezier(cbc1.toSBasis());
+ start_point = cubicBezier [2];
+ //stupid thing Inkscape does:
+ if (are_near(start_point, cross_point, 0.0000001)) {
+ start_point = cubicBezier [1];
}
-
- order = Outline::bezierOrder(&cbc2);
-
- switch (order) {
- case 3:
- end_point = (static_cast<const Geom::CubicBezier*>(&cbc2))->operator[] (1);
- if (are_near(end_point, cross_point, 0.0000001)) {
- end_point = (static_cast<const Geom::CubicBezier*>(&cbc2))->operator[] (2);
- }
- break;
- case 2:
- end_point = (static_cast<const Geom::QuadraticBezier*>(&cbc2))->operator[] (1);
- break;
- case 1:
- default:
- end_point = cbc2.finalPoint();
+ cubicBezier = Geom::sbasis_to_cubicbezier(cbc2.toSBasis());
+ end_point = cubicBezier [1];
+ if (are_near(end_point, cross_point, 0.0000001)) {
+ end_point = cubicBezier [2];
}
//got our three points, now let's see what their clockwise angle is
@@ -391,7 +370,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double
Geom::Path path_builder = Geom::Path(); //the path to store the result in
Geom::PathVector * path_vec; //needed because livarot returns a goddamn pointer
- const unsigned k = path_in.size();
+ const unsigned k = pv.size();
for (unsigned u = 0; u < k; u+=2) {
to_outline = Path();
diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h
index 27bc62d45..0ee0f261e 100644
--- a/src/live_effects/pathoutlineprovider.h
+++ b/src/live_effects/pathoutlineprovider.h
@@ -12,6 +12,12 @@ enum LineJoinType {
LINEJOIN_EXTRAPOLATED
};
+namespace Geom
+{
+ Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in);
+ std::vector<Geom::Path> split_at_cusps(const Geom::Path& in);
+}
+
namespace Outline
{
unsigned bezierOrder (const Geom::Curve* curve_in);