QPainterPath VariablePathShape::outline() const
{
QPainterPath path;
foreach(KoSubpath * subpath, m_subpaths) {
// go through forward
// add an offset to left
QPointF offset(-5.,0.);
KoPathPoint * lastPoint = subpath->first();
bool activeCP = false;
foreach(KoPathPoint * currPoint, *subpath) {
KoPathPoint::PointProperties currProperties = currPoint->properties();
if (currPoint == subpath->first()) {
if (currProperties & KoPathPoint::StartSubpath) {
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
path.moveTo(currPoint->point() + offset);
}
} else if (activeCP && currPoint->activeControlPoint1()) {
Q_ASSERT(!qIsNaNPoint(lastPoint->controlPoint2()));
Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
path.cubicTo(
lastPoint->controlPoint2() + offset,
currPoint->controlPoint1() + offset,
currPoint->point() + offset);
} else if( activeCP || currPoint->activeControlPoint1()) {
Q_ASSERT(!qIsNaNPoint(lastPoint->controlPoint2()));
Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
path.quadTo(
activeCP ? lastPoint->controlPoint2() + offset : currPoint->controlPoint1() + offset,
currPoint->point() + offset);
} else {
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
path.lineTo(currPoint->point() + offset);
}
if (currProperties & KoPathPoint::CloseSubpath && currProperties & KoPathPoint::StopSubpath) {
// add curve when there is a curve on the way to the first point
KoPathPoint * firstPoint = subpath->first();
Q_ASSERT(!qIsNaNPoint(firstPoint->point()));
if (currPoint->activeControlPoint2() && firstPoint->activeControlPoint1()) {
path.cubicTo(
currPoint->controlPoint2() + offset,
firstPoint->controlPoint1() + offset,
firstPoint->point() + offset);
}
else if(currPoint->activeControlPoint2() || firstPoint->activeControlPoint1()) {
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
path.quadTo(
currPoint->activeControlPoint2() ? currPoint->controlPoint2() + offset : firstPoint->controlPoint1() + offset,
firstPoint->point() + offset);
}
path.closeSubpath();
}
if (currPoint->activeControlPoint2()) {
activeCP = true;
} else {
activeCP = false;
}
lastPoint = currPoint;
}
offset = QPointF(5.0, 0);
// go through backward
// TODO
lastPoint = subpath->first();
activeCP = false;
foreach(KoPathPoint * currPoint, *subpath) {
KoPathPoint::PointProperties currProperties = currPoint->properties();
if (currPoint == subpath->first()) {
if (currProperties & KoPathPoint::StartSubpath) {
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
path.moveTo(currPoint->point() + offset);
}
} else if (activeCP && currPoint->activeControlPoint1()) {
Q_ASSERT(!qIsNaNPoint(lastPoint->controlPoint2()));
Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
path.cubicTo(
lastPoint->controlPoint2() + offset,
currPoint->controlPoint1() + offset,
currPoint->point() + offset);
} else if( activeCP || currPoint->activeControlPoint1()) {
Q_ASSERT(!qIsNaNPoint(lastPoint->controlPoint2()));
Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
path.quadTo(
activeCP ? lastPoint->controlPoint2() + offset : currPoint->controlPoint1() + offset,
currPoint->point() + offset);
} else {
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
path.lineTo(currPoint->point() + offset);
}
if (currProperties & KoPathPoint::CloseSubpath && currProperties & KoPathPoint::StopSubpath) {
// add curve when there is a curve on the way to the first point
KoPathPoint * firstPoint = subpath->first();
Q_ASSERT(!qIsNaNPoint(firstPoint->point()));
if (currPoint->activeControlPoint2() && firstPoint->activeControlPoint1()) {
path.cubicTo(
currPoint->controlPoint2() + offset,
firstPoint->controlPoint1() + offset,
firstPoint->point() + offset);
}
else if(currPoint->activeControlPoint2() || firstPoint->activeControlPoint1()) {
Q_ASSERT(!qIsNaNPoint(currPoint->point()));
Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
path.quadTo(
currPoint->activeControlPoint2() ? currPoint->controlPoint2() + offset : firstPoint->controlPoint1() + offset,
firstPoint->point() + offset);
}
path.closeSubpath();
}
if (currPoint->activeControlPoint2()) {
activeCP = true;
} else {
activeCP = false;
}
lastPoint = currPoint;
}
}
return path;
}