diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qbackingstore.cpp | 26 | ||||
-rw-r--r-- | src/gui/painting/qblendfunctions_p.h | 53 | ||||
-rw-r--r-- | src/gui/painting/qcompositionfunctions.cpp | 8 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 40 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster_p.h | 3 | ||||
-rw-r--r-- | src/gui/painting/qpathclipper_p.h | 6 | ||||
-rw-r--r-- | src/gui/painting/qstroker.cpp | 3 |
7 files changed, 59 insertions, 80 deletions
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 2147d9d61d..703c492a6b 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -320,32 +320,34 @@ bool QBackingStore::hasStaticContents() const void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset) { // make sure we don't detach - uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits()); + uchar *mem = const_cast<uchar*>(img.constBits()); int lineskip = img.bytesPerLine(); int depth = img.depth() >> 3; const QRect imageRect(0, 0, img.width(), img.height()); - const QRect r = rect & imageRect & imageRect.translated(-offset); - const QPoint p = rect.topLeft() + offset; - - if (r.isEmpty()) + const QRect sourceRect = rect.intersected(imageRect).intersected(imageRect.translated(-offset)); + if (sourceRect.isEmpty()) return; + const QRect destRect = sourceRect.translated(offset); + Q_ASSERT_X(imageRect.contains(destRect), "qt_scrollRectInImage", + "The sourceRect should already account for clipping, both pre and post scroll"); + const uchar *src; uchar *dest; - if (r.top() < p.y()) { - src = mem + r.bottom() * lineskip + r.left() * depth; - dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth; + if (sourceRect.top() < destRect.top()) { + src = mem + sourceRect.bottom() * lineskip + sourceRect.left() * depth; + dest = mem + (destRect.top() + sourceRect.height() - 1) * lineskip + destRect.left() * depth; lineskip = -lineskip; } else { - src = mem + r.top() * lineskip + r.left() * depth; - dest = mem + p.y() * lineskip + p.x() * depth; + src = mem + sourceRect.top() * lineskip + sourceRect.left() * depth; + dest = mem + destRect.top() * lineskip + destRect.left() * depth; } - const int w = r.width(); - int h = r.height(); + const int w = sourceRect.width(); + int h = sourceRect.height(); const int bytes = w * depth; // overlapping segments? diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h index 080da98ec4..6997d62b3c 100644 --- a/src/gui/painting/qblendfunctions_p.h +++ b/src/gui/painting/qblendfunctions_p.h @@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, int dudx, int dvdx, int dudy, int dvdy, int u0, int v0, Blender blender) { - int fromY = qMax(qRound(topY), clip.top()); - int toY = qMin(qRound(bottomY), clip.top() + clip.height()); + qint64 fromY = qMax(qRound(topY), clip.top()); + qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height()); if (fromY >= toY) return; qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y); qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y); - int dx_l = int(leftSlope * 0x10000); - int dx_r = int(rightSlope * 0x10000); - int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000); - int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000); - - int fromX, toX, x1, x2, u, v, i, ii; + qint64 dx_l = qint64(leftSlope * 0x10000); + qint64 dx_r = qint64(rightSlope * 0x10000); + qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000); + qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000); + + qint64 sourceRectTop = qint64(sourceRect.top()); + qint64 sourceRectLeft = qint64(sourceRect.left()); + qint64 sourceRectWidth = qint64(sourceRect.width()); + qint64 sourceRectHeight = qint64(sourceRect.height()); + qint64 clipLeft = qint64(clip.left()); + qint64 clipWidth = qint64(clip.width()); + + qint64 fromX, toX, x1, x2, u, v, i, ii; DestT *line; - for (int y = fromY; y < toY; ++y) { + for (qint64 y = fromY; y < toY; ++y) { line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl); - fromX = qMax(x_l >> 16, clip.left()); - toX = qMin(x_r >> 16, clip.left() + clip.width()); + fromX = qMax(x_l >> 16, clipLeft); + toX = qMin(x_r >> 16, clipLeft + clipWidth); if (fromX < toX) { // Because of rounding, we can get source coordinates outside the source image. // Clamp these coordinates to the source rect to avoid segmentation fault and @@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, u = x1 * dudx + y * dudy + u0; v = x1 * dvdx + y * dvdy + v0; for (; x1 < toX; ++x1) { - int uu = u >> 16; - int vv = v >> 16; - if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() - && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { + qint64 uu = u >> 16; + qint64 vv = v >> 16; + if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth + && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) { break; } u += dudx; @@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, u = (x2 - 1) * dudx + y * dudy + u0; v = (x2 - 1) * dvdx + y * dvdy + v0; for (; x2 > x1; --x2) { - int uu = u >> 16; - int vv = v >> 16; - if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() - && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { + qint64 uu = u >> 16; + qint64 vv = v >> 16; + if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth + && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) { break; } u -= dudx; @@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, // Beginning of the scan line, with per-pixel checks. i = x1 - fromX; while (i) { - int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); - int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); + qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1); + qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1); blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]); u += dudx; v += dvdx; @@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, // End of the scan line, with per-pixel checks. i = toX - x2; while (i) { - int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); - int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); + qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1); + qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1); blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]); u += dudx; v += dvdx; diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp index ced213e36d..aa3f148934 100644 --- a/src/gui/painting/qcompositionfunctions.cpp +++ b/src/gui/painting/qcompositionfunctions.cpp @@ -1045,12 +1045,12 @@ private: static inline int mix_alpha(int da, int sa) { - return 255 - ((255 - sa) * (255 - da) >> 8); + return 255 - qt_div_255((255 - sa) * (255 - da)); } static inline uint mix_alpha_rgb64(uint da, uint sa) { - return 65535 - ((65535 - sa) * (65535 - da) >> 16); + return 65535U - qt_div_65535((65535U - sa) * (65535U - da)); } /* @@ -1337,7 +1337,7 @@ static inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint int da = qAlpha(d); int sa = qAlpha(s); -#define OP(a, b) 255 - (((255-a) * (255-b)) >> 8) +#define OP(a, b) 255 - qt_div_255((255-a) * (255-b)) int r = OP( qRed(d), qRed(s)); int b = OP( qBlue(d), qBlue(s)); int g = OP(qGreen(d), qGreen(s)); @@ -1367,7 +1367,7 @@ static inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QR uint da = d.alpha(); uint sa = s.alpha(); -#define OP(a, b) 65535 - (((65535-a) * (65535-b)) >> 16) +#define OP(a, b) 65535U - qt_div_65535((65535U-a) * (65535U-b)) uint r = OP( d.red(), s.red()); uint b = OP( d.blue(), s.blue()); uint g = OP(d.green(), s.green()); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 283923de52..38bad9a6b0 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix) QRasterPaintEngineState *s = state(); // FALCON: get rid of this line, see drawImage call below. s->matrix = matrix; - QTransform::TransformationType txop = s->matrix.type(); - - switch (txop) { - - case QTransform::TxNone: - s->flags.int_xform = true; - break; - - case QTransform::TxTranslate: - s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx() - && qreal(int(s->matrix.dy())) == s->matrix.dy(); - break; - - case QTransform::TxScale: - s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx() - && qreal(int(s->matrix.dy())) == s->matrix.dy() - && qreal(int(s->matrix.m11())) == s->matrix.m11() - && qreal(int(s->matrix.m22())) == s->matrix.m22(); - break; - - default: // shear / perspective... - s->flags.int_xform = false; - break; - } - s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale); ensureOutlineMapper(); @@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState() flags.bilinear = false; flags.legacy_rounding = false; flags.fast_text = true; - flags.int_xform = true; flags.tx_noshear = true; flags.fast_images = true; @@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) QRectF cpRect = path.controlPointRect(); const QRectF pathDeviceRect = s->matrix.mapRect(cpRect); // Skip paths that by conservative estimates are completely outside the paint device. - if (!pathDeviceRect.intersects(QRectF(d->deviceRect))) + if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid()) return; ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData); @@ -3095,10 +3069,10 @@ QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect, static QPair<int, int> visibleGlyphRange(const QRectF &clip, QFontEngine *fontEngine, glyph_t *glyphs, QFixedPoint *positions, int numGlyphs) { - QFixed clipLeft = QFixed::fromReal(clip.left()); - QFixed clipRight = QFixed::fromReal(clip.right()); - QFixed clipTop = QFixed::fromReal(clip.top()); - QFixed clipBottom = QFixed::fromReal(clip.bottom()); + QFixed clipLeft = QFixed::fromReal(clip.left() - 1); + QFixed clipRight = QFixed::fromReal(clip.right() + 1); + QFixed clipTop = QFixed::fromReal(clip.top() - 1); + QFixed clipBottom = QFixed::fromReal(clip.bottom() + 1); int first = 0; while (first < numGlyphs) { @@ -3585,7 +3559,7 @@ QRasterPaintEngine::ClipType QRasterPaintEngine::clipType() const \internal Returns the bounding rect of the currently set clip. */ -QRect QRasterPaintEngine::clipBoundingRect() const +QRectF QRasterPaintEngine::clipBoundingRect() const { Q_D(const QRasterPaintEngine); @@ -3597,7 +3571,7 @@ QRect QRasterPaintEngine::clipBoundingRect() const if (clip->hasRectClip) return clip->clipRect; - return QRect(clip->xmin, clip->ymin, clip->xmax - clip->xmin, clip->ymax - clip->ymin); + return QRectF(clip->xmin, clip->ymin, clip->xmax - clip->xmin, clip->ymax - clip->ymin); } void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data) diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 089aadc3f7..7b15292ebb 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -111,7 +111,6 @@ public: uint bilinear : 1; uint legacy_rounding : 1; uint fast_text : 1; - uint int_xform : 1; uint tx_noshear : 1; uint fast_images : 1; }; @@ -206,7 +205,7 @@ public: ComplexClip }; ClipType clipType() const; - QRect clipBoundingRect() const; + QRectF clipBoundingRect() const; #ifdef Q_OS_WIN void setDC(HDC hdc); diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h index 9444a87b71..18f64c5e8c 100644 --- a/src/gui/painting/qpathclipper_p.h +++ b/src/gui/painting/qpathclipper_p.h @@ -156,7 +156,7 @@ public: int vertex(Direction direction) const; private: - int m_next[2][2]; + int m_next[2][2] = { { -1, -1 }, { -1, -1 } }; }; class QPathSegments @@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b) , angle(0) , invAngle(0) { - m_next[0][0] = -1; - m_next[1][0] = -1; - m_next[0][0] = -1; - m_next[1][0] = -1; } inline int QPathEdge::next(Traversal traversal, Direction direction) const diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index cb5d395e80..3b6357a893 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath() // Check if the entire line should be clipped away or simplified bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br); bool skipDashing = elen * invSumLength > repetitionLimit(); + int maxDashes = dashCount; if (skipDashing || clipIt) { // Cut away full dash sequences. elen -= std::floor(elen * invSumLength) * sumLength; @@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath() pos = estop; // move pos to next path element done = true; } else { // Dash is on this line - pos = dpos + estart; + pos = --maxDashes > 0 ? dpos + estart : estop; done = pos >= estop; if (++idash >= dashCount) idash = 0; |