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:
parent
757d4b85a9
commit
7a4ebf1b71
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user