Fix drawing of 0-width polylines from outside the devicerect.
This was broken by a previous fix which aimed to fix gaps in polylines with tiny line segments. The result was that we skipped updating the origin point when stroke() didn't produce pixels which accidentally included the case of the line being completely outside the deviceRect. I fixed this by returning the value of clipLine in drawLine to the caller so we could still update the origin for this case. Task-number: QTBUG-31579 Change-Id: Iac29436f042da7658bbeaf9370351dc6f2c95065 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
1937012b3e
commit
900cccfd45
@ -133,10 +133,15 @@ struct NoDasher {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* The return value is the result of the clipLine() call performed at the start
|
||||
* of each of the two functions, aka "false" means completely outside the devices
|
||||
* rect.
|
||||
*/
|
||||
template<DrawPixel drawPixel, class Dasher>
|
||||
static void drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
|
||||
static bool drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
|
||||
template<DrawPixel drawPixel, class Dasher>
|
||||
static void drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
|
||||
static bool drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
|
||||
|
||||
inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage)
|
||||
{
|
||||
@ -602,17 +607,20 @@ void QCosmeticStroker::drawPath(const QVectorPath &path)
|
||||
caps |= CapEnd;
|
||||
|
||||
QCosmeticStroker::Point last = this->lastPixel;
|
||||
stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
|
||||
bool unclipped = stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
|
||||
|
||||
/* fix for gaps in polylines with fastpen and aliased in a sequence
|
||||
of points with small distances: if current point p2 has been dropped
|
||||
out, keep last non dropped point p. */
|
||||
if (fastPenAliased) {
|
||||
if (last.x != lastPixel.x || last.y != lastPixel.y ||
|
||||
points == begin + 2 || points == end - 2 ) {
|
||||
{
|
||||
p = p2;
|
||||
}
|
||||
out, keep last non dropped point p.
|
||||
|
||||
However, if the line was completely outside the devicerect, we
|
||||
still need to update p to avoid drawing the line after this one from
|
||||
a bad starting position.
|
||||
*/
|
||||
if (fastPenAliased && unclipped) {
|
||||
if (last.x != lastPixel.x || last.y != lastPixel.y
|
||||
|| points == begin + 2 || points == end - 2) {
|
||||
p = p2;
|
||||
}
|
||||
} else {
|
||||
p = p2;
|
||||
@ -720,10 +728,10 @@ static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc)
|
||||
the drawing shifts from horizontal to vertical or back.
|
||||
*/
|
||||
template<DrawPixel drawPixel, class Dasher>
|
||||
static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
|
||||
static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
|
||||
{
|
||||
if (stroker->clipLine(rx1, ry1, rx2, ry2))
|
||||
return;
|
||||
return false;
|
||||
|
||||
const int half = stroker->legacyRounding ? 31 : 0;
|
||||
int x1 = toF26Dot6(rx1) + half;
|
||||
@ -813,7 +821,7 @@ static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
} else {
|
||||
// horizontal
|
||||
if (!dx)
|
||||
return;
|
||||
return true;
|
||||
|
||||
QCosmeticStroker::Direction dir = QCosmeticStroker::LeftToRight;
|
||||
|
||||
@ -886,14 +894,15 @@ static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
}
|
||||
}
|
||||
stroker->lastPixel = last;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<DrawPixel drawPixel, class Dasher>
|
||||
static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
|
||||
static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
|
||||
{
|
||||
if (stroker->clipLine(rx1, ry1, rx2, ry2))
|
||||
return;
|
||||
return false;
|
||||
|
||||
int x1 = toF26Dot6(rx1);
|
||||
int y1 = toF26Dot6(ry1);
|
||||
@ -967,7 +976,7 @@ static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
|
||||
} else {
|
||||
// horizontal
|
||||
if (!dx)
|
||||
return;
|
||||
return true;
|
||||
|
||||
int yinc = F16Dot16FixedDiv(dy, dx);
|
||||
|
||||
@ -1029,6 +1038,7 @@ static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
|
||||
drawPixel(stroker, x, (y>>16) + 1, alpha * alphaEnd >> 6);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QCosmeticStroker;
|
||||
|
||||
|
||||
typedef void (*StrokeLine)(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
|
||||
typedef bool (*StrokeLine)(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
|
||||
|
||||
class QCosmeticStroker
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user