summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiam P. White <inkscapebronyat-signgmaildotcom>2014-04-12 18:18:31 +0000
committerLiam P. White <inkscapebronyat-signgmaildotcom>2014-04-12 18:18:31 +0000
commit727826e1fdd2c4142b1687e50c174ed14c178427 (patch)
treed54c6ba9dceb94e6c4aecf7000ecc99f783afd45 /src
parentUpdate to trunk (diff)
downloadinkscape-727826e1fdd2c4142b1687e50c174ed14c178427.tar.gz
inkscape-727826e1fdd2c4142b1687e50c174ed14c178427.zip
Fix triangles in joins
(bzr r13090.1.52)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-taperstroke.cpp58
-rw-r--r--src/live_effects/pathoutlineprovider.cpp45
2 files changed, 65 insertions, 38 deletions
diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp
index ce07ed962..2400b3e37 100644
--- a/src/live_effects/lpe-taperstroke.cpp
+++ b/src/live_effects/lpe-taperstroke.cpp
@@ -197,6 +197,8 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
bool zeroStart = false;
bool zeroEnd = false;
+ bool metInMiddle = false;
+
//there is a pretty good chance that people will try to drag the knots
//on top of each other, so block it
@@ -208,6 +210,10 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
attach_end.param_set_value( size - attach_start );
}
}
+
+ if (attach_start == size - attach_end) {
+ metInMiddle = true;
+ }
//don't let it be zero
if (attach_start <= 0.00000001) {
@@ -232,10 +238,10 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
//don't let the knots be farther than they are allowed to be
if ((unsigned)attach_start >= allowed_start) {
- attach_start.param_set_value((double)allowed_start - 0.00000001);
+ attach_start.param_set_value((double)allowed_start - 0.00001);
}
if ((unsigned)attach_end >= allowed_end) {
- attach_end.param_set_value((double)allowed_end - 0.00000001);
+ attach_end.param_set_value((double)allowed_end - 0.00001);
}
//remember, Path::operator () means get point at time t
@@ -265,11 +271,14 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in)
real_path.append(throwaway_path);
}
- //append the outside outline of the path (with direction)
- throwaway_path = Outline::PathOutsideOutline(pathv_out[1],
- -fabs(line_width), static_cast<LineJoinType>(join_type.get_value()), miter_limit);
+
+ if (!metInMiddle) {
+ //append the outside outline of the path (with direction)
+ throwaway_path = Outline::PathOutsideOutline(pathv_out[1],
+ -fabs(line_width), static_cast<LineJoinType>(join_type.get_value()), miter_limit);
- real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS);
+ real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS);
+ }
if (!zeroEnd) {
//append the ending taper
@@ -460,32 +469,17 @@ Geom::Piecewise<Geom::D2<Geom::SBasis> > stretch_along(Geom::Piecewise<Geom::D2<
void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second)
{
- unsigned order = Outline::bezierOrder(curve_in);
- switch (order) {
- case 3: {
- Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_in);
- std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide(t);
- //trimmed_start.append(cb_pair.first);
- val_first = cb_pair.first.duplicate();
- val_second = cb_pair.second.duplicate();
- break;
- }
- case 2: {
- Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_in);
- std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide(t);
- //trimmed_start.append(qb_pair.first);
- val_first = qb_pair.first.duplicate();
- val_second = qb_pair.second.duplicate();
- break;
- }
- case 1: {
- Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_in);
- std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t);
- //trimmed_start.append(lb_pair.first);
- val_first = lb_pair.first.duplicate();
- val_second = lb_pair.second.duplicate();
- break;
- }
+ if (Geom::LineSegment* linear = dynamic_cast<Geom::LineSegment*>(curve_in)) {
+ //special case for line segments
+ std::pair<Geom::LineSegment, Geom::LineSegment> seg_pair = linear->subdivide(t);
+ val_first = seg_pair.first.duplicate();
+ val_second = seg_pair.second.duplicate();
+ } else {
+ //all other cases:
+ Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(curve_in->toSBasis());
+ std::pair<Geom::CubicBezier, Geom::CubicBezier> cubic_pair = cubic.subdivide(t);
+ val_first = cubic_pair.first.duplicate();
+ val_second = cubic_pair.second.duplicate();
}
}
diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp
index 5a95da75d..080f42c08 100644
--- a/src/live_effects/pathoutlineprovider.cpp
+++ b/src/live_effects/pathoutlineprovider.cpp
@@ -261,6 +261,7 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve
}
path_builder.appendNew<Geom::LineSegment> (endPt);
}
+ path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS);
}
if ( outside && lineProblem ) {
Geom::Path pth;
@@ -282,9 +283,22 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve
}
}
path_builder.appendNew<Geom::LineSegment> (endPt);
+ path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS);
}
if ( !outside ) {
- path_builder.appendNew<Geom::LineSegment> (endPt);
+ /*path_builder.appendNew<Geom::LineSegment> (endPt);*/
+ Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
+ if (!cross.empty()) {
+ path_builder.erase_last();
+ Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(cbc1->toSBasis());
+ cubic = cubic.subdivide(cross[0].ta).first;
+ path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS);
+ cubic = Geom::sbasis_to_cubicbezier(cbc2->toSBasis());
+ cubic = cubic.subdivide(cross[0].tb).second;
+ path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS);
+ } else {
+ path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS);
+ }
}
}
@@ -346,9 +360,22 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb
path_builder.appendNew <Geom::CubicBezier> (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] );
path_builder.appendNew <Geom::CubicBezier> (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt );
}
- } else { // cross.empty()
+ path_builder.append(*cbc2);
+ } else {
//probably on the inside of the corner
- path_builder.appendNew<Geom::LineSegment> ( endPt );
+ /*path_builder.appendNew<Geom::LineSegment> ( endPt );*/
+ cross = Geom::crossings(*cbc1, *cbc2);
+ if (!cross.empty()) {
+ path_builder.erase_last();
+ Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(cbc1->toSBasis());
+ cubic = cubic.subdivide(cross[0].ta).first;
+ path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS);
+ cubic = Geom::sbasis_to_cubicbezier(cbc2->toSBasis());
+ cubic = cubic.subdivide(cross[0].tb).second;
+ path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS);
+ } else {
+ path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS);
+ }
}
}
@@ -387,6 +414,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double
if (u == 0) {
//I could use the pv->operator[] (0) notation but that looks terrible
path_builder.start( (*path_vec)[0].initialPoint() );
+ path_builder.append( (*path_vec)[0] );
} else {
//get the curves ready for the operation
Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate();
@@ -400,10 +428,12 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double
reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width,
outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] ));
}
+ Geom::Path temp_path = (*path_vec)[0];
+ temp_path.erase(temp_path.begin());
+
+ path_builder.append( temp_path );
}
- path_builder.append( (*path_vec)[0] );
-
//outline the next segment, but don't store it yet
if (path_vec) delete path_vec;
@@ -430,7 +460,10 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double
}
//Now we can store it.
- path_builder.append( (*path_vec)[0] );
+ Geom::Path temp_path = (*path_vec)[0];
+ temp_path.erase(temp_path.begin());
+
+ path_builder.append( temp_path );
if (cbc1) delete cbc1;
if (cbc2) delete cbc2;