summaryrefslogtreecommitdiffstats
path: root/src/livarot/PathOutline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/livarot/PathOutline.cpp')
-rw-r--r--src/livarot/PathOutline.cpp75
1 files changed, 46 insertions, 29 deletions
diff --git a/src/livarot/PathOutline.cpp b/src/livarot/PathOutline.cpp
index d170e5d3a..211ee31e2 100644
--- a/src/livarot/PathOutline.cpp
+++ b/src/livarot/PathOutline.cpp
@@ -387,7 +387,7 @@ void Path::SubContractOutline(int off, int num_pd,
if (closeIfNeeded) {
if ( Geom::LInfty (curX- firstP) < 0.0001 ) {
OutlineJoin (dest, firstP, curT, firstT, width, join,
- miter);
+ miter, nType);
dest->Close ();
} else {
PathDescrLineTo temp(firstP);
@@ -404,7 +404,7 @@ void Path::SubContractOutline(int off, int num_pd,
Geom::Point pos;
pos = curX;
OutlineJoin (dest, pos, curT, stNor, width, join,
- miter);
+ miter, nType);
}
dest->LineTo (enPos+width*enNor);
@@ -413,7 +413,7 @@ void Path::SubContractOutline(int off, int num_pd,
Geom::Point pos;
pos = firstP;
OutlineJoin (dest, enPos, enNor, firstT, width, join,
- miter);
+ miter, nType);
dest->Close ();
}
}
@@ -429,7 +429,7 @@ void Path::SubContractOutline(int off, int num_pd,
if (Geom::LInfty (curX - firstP) < 0.0001)
{
OutlineJoin (dest, firstP, curT, firstT, width, join,
- miter);
+ miter, nType);
dest->Close ();
}
else
@@ -445,7 +445,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
{
OutlineJoin (dest, stPos, curT, stNor, width, join,
- miter);
+ miter, nType);
}
dest->LineTo (enPos+width*enNor);
@@ -453,7 +453,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
{
OutlineJoin (dest, enPos, enNor, firstT, width, join,
- miter);
+ miter, nType);
dest->Close ();
}
}
@@ -465,15 +465,15 @@ void Path::SubContractOutline(int off, int num_pd,
{
PathDescrLineTo* nData = dynamic_cast<PathDescrLineTo*>(descr_cmd[curD]);
nextX = nData->p;
+ // et on avance
+ TangentOnSegAt (0.0, curX, *nData, stPos, stTgt, stTle);
+ TangentOnSegAt (1.0, curX, *nData, enPos, enTgt, enTle);
// test de nullité du segment
if (IsNulCurve (descr_cmd, curD, curX))
{
- curP++;
- continue;
+ stTgt = dest->descr_cmd.size() ? Geom::Point(1, 0) : Geom::Point(-1, 0); // reverse direction
+ enTgt = stTgt;
}
- // et on avance
- TangentOnSegAt (0.0, curX, *nData, stPos, stTgt, stTle);
- TangentOnSegAt (1.0, curX, *nData, enPos, enTgt, enTle);
stNor=stTgt.cw();
enNor=enTgt.cw();
@@ -497,7 +497,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
Geom::Point pos;
pos = curX;
- OutlineJoin (dest, pos, curT, stNor, width, join, miter);
+ OutlineJoin (dest, pos, curT, stNor, width, join, miter, nType);
}
int n_d = dest->LineTo (nextX+width*enNor);
@@ -547,7 +547,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
Geom::Point pos;
pos = curX;
- OutlineJoin (dest, pos, curT, stNor, width, join, miter);
+ OutlineJoin (dest, pos, curT, stNor, width, join, miter, nType);
}
callsData.piece = curP;
@@ -603,7 +603,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
Geom::Point pos;
pos = curX;
- OutlineJoin (dest, pos, curT, stNor, width, join, miter);
+ OutlineJoin (dest, pos, curT, stNor, width, join, miter, nType);
}
callsData.piece = curP;
@@ -661,7 +661,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
Geom::Point pos;
pos = curX;
- if (stTle > 0) OutlineJoin (dest, pos, curT, stNor, width, join, miter);
+ if (stTle > 0) OutlineJoin (dest, pos, curT, stNor, width, join, miter, nType);
}
int n_d = dest->LineTo (nextX+width*enNor);
if (n_d >= 0) {
@@ -692,7 +692,7 @@ void Path::SubContractOutline(int off, int num_pd,
// jointure
Geom::Point pos;
pos = curX;
- OutlineJoin (dest, pos, curT, stNor, width, join, miter);
+ OutlineJoin (dest, pos, curT, stNor, width, join, miter, nType);
}
callsData.piece = curP;
@@ -709,9 +709,8 @@ void Path::SubContractOutline(int off, int num_pd,
} else if (nbInterm > 1) {
Geom::Point bx=curX;
Geom::Point cx=curX;
- Geom::Point dx=curX;
+ Geom::Point dx=nData->p;
- dx = nData->p;
TangentOnBezAt (0.0, curX, *nData, *nBData, false, stPos, stTgt, stTle, stRad);
stNor=stTgt.cw();
@@ -729,7 +728,7 @@ void Path::SubContractOutline(int off, int num_pd,
} else {
// jointure
Geom::Point pos=curX;
- OutlineJoin (dest, pos, stTgt, stNor, width, join, miter);
+ OutlineJoin (dest, pos, stTgt, stNor, width, join, miter, nType);
// dest->LineTo(curX+width*stNor.x,curY+width*stNor.y);
}
}
@@ -931,7 +930,7 @@ void Path::TangentOnArcAt(double at, const Geom::Point &iS, PathDescrArcTo const
Geom::Point const iE = fin.p;
double const rx = fin.rx;
double const ry = fin.ry;
- double const angle = fin.angle;
+ double const angle = fin.angle*M_PI/180.0;
bool const large = fin.large;
bool const wise = fin.clockwise;
@@ -1048,7 +1047,7 @@ void Path::TangentOnArcAt(double at, const Geom::Point &iS, PathDescrArcTo const
dtgt[0] = -ca * rx * cb + sa * ry * sb;
dtgt[1] = -sa * rx * cb - ca * ry * sb;
len = L2(tgt);
- rad = len * dot(tgt, tgt) / (tgt[0] * dtgt[1] - tgt[1] * dtgt[0]);
+ rad = -len * dot(tgt, tgt) / (tgt[0] * dtgt[1] - tgt[1] * dtgt[0]);
tgt /= len;
}
else
@@ -1164,7 +1163,7 @@ Path::TangentOnBezAt (double at, Geom::Point const &iS,
void
Path::OutlineJoin (Path * dest, Geom::Point pos, Geom::Point stNor, Geom::Point enNor, double width,
- JoinType join, double miter)
+ JoinType join, double miter, int nType)
{
/*
Arbitrarily decide if we're on the inside or outside of a half turn.
@@ -1184,12 +1183,24 @@ Path::OutlineJoin (Path * dest, Geom::Point pos, Geom::Point stNor, Geom::Point
const double angSi = cross (enNor,stNor);
const double angCo = dot (stNor, enNor);
- if (angSi == 0 && angCo > 0) { // The join is straight -> nothing to do.
+ if ((fabs(angSi) < .0000001) && angCo > 0) { // The join is straight -> nothing to do.
} else {
if ((angSi > 0 && width >= 0)
|| (angSi < 0 && width < 0)) { // This is an inside join -> join is independent of chosen JoinType.
- dest->LineTo (pos);
- dest->LineTo (pos + width*enNor);
+ if ((dest->descr_cmd[dest->descr_cmd.size() - 1]->getType() == descr_lineto) && (nType == descr_lineto)) {
+ Geom::Point const biss = unit_vector(Geom::rot90( stNor - enNor ));
+ double c2 = Geom::dot (biss, enNor);
+ if (fabs(c2) > 0.707107) { // apply only to obtuse angles
+ double l = width / c2;
+ PathDescrLineTo* nLine = dynamic_cast<PathDescrLineTo*>(dest->descr_cmd[dest->descr_cmd.size() - 1]);
+ nLine->p = pos + l*biss; // relocate to bisector
+ } else {
+ dest->LineTo (pos + width*enNor);
+ }
+ } else {
+// dest->LineTo (pos); // redundant
+ dest->LineTo (pos + width*enNor);
+ }
} else if (angSi == 0 && TurnInside) { // Half turn (180 degrees) ... inside (see above).
dest->LineTo (pos + width*enNor);
} else { // This is an outside join -> chosen JoinType should be applied.
@@ -1241,8 +1252,14 @@ Path::OutlineJoin (Path * dest, Geom::Point pos, Geom::Point stNor, Geom::Point
if ( fabs(l) > miter) {
dest->LineTo (pos + width*enNor);
} else {
- dest->LineTo (pos+l*biss);
- dest->LineTo (pos+width*enNor);
+ if (dest->descr_cmd[dest->descr_cmd.size() - 1]->getType() == descr_lineto) {
+ PathDescrLineTo* nLine = dynamic_cast<PathDescrLineTo*>(dest->descr_cmd[dest->descr_cmd.size() - 1]);
+ nLine->p = pos+l*biss; // relocate to bisector
+ } else {
+ dest->LineTo (pos+l*biss);
+ }
+ if (nType != descr_lineto)
+ dest->LineTo (pos+width*enNor);
}
} else { // Bevel join
dest->LineTo (pos + width*enNor);
@@ -1425,7 +1442,7 @@ Path::RecStdArcTo (outline_callback_data * data, double tol, double width,
{
Geom::Point tms(data->x1,data->y1),tme(data->x2,data->y2);
ArcAngles (tms,tme, data->d.a.rx,
- data->d.a.ry, data->d.a.angle, data->d.a.large, !data->d.a.clock,
+ data->d.a.ry, data->d.a.angle*M_PI/180.0, data->d.a.large, !data->d.a.clock,
sang, eang);
}
double scal = eang - sang;
@@ -1459,7 +1476,7 @@ Path::RecStdArcTo (outline_callback_data * data, double tol, double width,
}
const Geom::Point diff = req - chk;
const double err = (dot(diff,diff));
- if (err <= tol * tol)
+ if (err <= tol) // tolerance is given as a quadratic value, no need to use tol*tol here
{
int n_d = data->dest->CubicTo (enPos + width*enNor,
stGue*scal*stTgt,