Painting: Fix capping of polylines having endpoint == startpoint

A polyline should not be closed like a polygon, even if the start and
end points are identical. But when the primitive was broken down to a
vector path, the stroker no longer had available the information that
it should be open, and so would join the start and end points.

Fixes: QTBUG-65393
Change-Id: I0a566f91cf1a2843fda662b393dbae78c3c38f06
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Eirik Aavitsland 2018-10-09 16:42:03 +02:00
parent 757d4b85a9
commit 7a4ebf1b71
4 changed files with 15 additions and 4 deletions

View File

@ -439,6 +439,9 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
}
}
if (d->activeStroker == &d->stroker)
d->stroker.setForceOpen(path.hasExplicitOpen());
const QPainterPath::ElementType *types = path.elements();
const qreal *points = path.points();
int pointCount = path.elementCount();

View File

@ -369,7 +369,8 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform
QStroker::QStroker()
: m_capStyle(SquareJoin), m_joinStyle(FlatJoin),
m_back1X(0), m_back1Y(0),
m_back2X(0), m_back2Y(0)
m_back2X(0), m_back2Y(0),
m_forceOpen(false)
{
m_strokeWidth = qt_real_to_fixed(1);
m_miterLimit = qt_real_to_fixed(2);
@ -748,7 +749,7 @@ template <class Iterator> bool qt_stroke_side(Iterator *it,
}
}
if (start == prev) {
if (start == prev && !stroker->forceOpen()) {
// closed subpath, join first and last point
#ifdef QPP_STROKE_DEBUG
qDebug("\n ---> (side) closed subpath");

View File

@ -222,6 +222,9 @@ public:
void setMiterLimit(qfixed length) { m_miterLimit = length; }
qfixed miterLimit() const { return m_miterLimit; }
void setForceOpen(bool state) { m_forceOpen = state; }
bool forceOpen() { return m_forceOpen; }
void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
inline void emitMoveTo(qfixed x, qfixed y);
inline void emitLineTo(qfixed x, qfixed y);
@ -247,6 +250,8 @@ protected:
qfixed m_back2X;
qfixed m_back2Y;
bool m_forceOpen;
};
class Q_GUI_EXPORT QDashStroker : public QStrokerOps

View File

@ -99,7 +99,8 @@ public:
// Shape rendering specifiers...
OddEvenFill = 0x1000,
WindingFill = 0x2000,
ImplicitClose = 0x4000
ImplicitClose = 0x4000,
ExplicitOpen = 0x8000
};
// ### Falcon: introduca a struct XY for points so lars is not so confused...
@ -124,6 +125,7 @@ public:
inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; }
inline bool hasImplicitClose() const { return m_hints & ImplicitClose; }
inline bool hasExplicitOpen() const { return m_hints & ExplicitOpen; }
inline bool hasWindingFill() const { return m_hints & WindingFill; }
inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; }
@ -142,7 +144,7 @@ public:
case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose;
case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose;
case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose;
case QPaintEngine::PolylineMode: return PolygonHint;
case QPaintEngine::PolylineMode: return PolygonHint | ExplicitOpen;
default: return 0;
}
}