diff options
-rw-r--r-- | src/gui/painting/qoutlinemapper.cpp | 30 | ||||
-rw-r--r-- | src/gui/painting/qoutlinemapper_p.h | 3 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 8 |
3 files changed, 24 insertions, 17 deletions
diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp index 0dfb310ee9..93eac5cced 100644 --- a/src/gui/painting/qoutlinemapper.cpp +++ b/src/gui/painting/qoutlinemapper.cpp @@ -37,6 +37,24 @@ static const QRectF boundingRect(const QPointF *points, int pointCount) return QRectF(QPointF(minx, miny), QPointF(maxx, maxy)); } +void QOutlineMapper::setClipRect(QRect clipRect) +{ + auto limitCoords = [](QRect r) { + const QRect limitRect(QPoint(-QT_RASTER_COORD_LIMIT, -QT_RASTER_COORD_LIMIT), + QPoint(QT_RASTER_COORD_LIMIT, QT_RASTER_COORD_LIMIT)); + r &= limitRect; + r.setWidth(qMin(r.width(), QT_RASTER_COORD_LIMIT)); + r.setHeight(qMin(r.height(), QT_RASTER_COORD_LIMIT)); + return r; + }; + + if (clipRect != m_clip_rect) { + m_clip_rect = limitCoords(clipRect); + const int mw = 64; // margin width. No need to trigger clipping for slight overshooting + m_clip_trigger_rect = QRectF(limitCoords(m_clip_rect.adjusted(-mw, -mw, mw, mw))); + } +} + void QOutlineMapper::curveTo(const QPointF &cp1, const QPointF &cp2, const QPointF &ep) { #ifdef QT_DEBUG_CONVERT printf("QOutlineMapper::curveTo() (%f, %f)\n", ep.x(), ep.y()); @@ -200,16 +218,8 @@ void QOutlineMapper::endOutline() m_clip_rect.x(), m_clip_rect.y(), m_clip_rect.width(), m_clip_rect.height()); #endif - - // Check for out of dev bounds... - const bool do_clip = !m_in_clip_elements && ((controlPointRect.left() < -QT_RASTER_COORD_LIMIT - || controlPointRect.right() > QT_RASTER_COORD_LIMIT - || controlPointRect.top() < -QT_RASTER_COORD_LIMIT - || controlPointRect.bottom() > QT_RASTER_COORD_LIMIT - || controlPointRect.width() > QT_RASTER_COORD_LIMIT - || controlPointRect.height() > QT_RASTER_COORD_LIMIT)); - - if (do_clip) { + // Avoid rasterizing outside cliprect: faster, and ensures coords < QT_RASTER_COORD_LIMIT + if (!m_in_clip_elements && !m_clip_trigger_rect.contains(controlPointRect)) { clipElements(elements, elementTypes(), m_elements.size()); } else { convertElements(elements, elementTypes(), m_elements.size()); diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h index 372f9b4ec2..1ce82eff0b 100644 --- a/src/gui/painting/qoutlinemapper_p.h +++ b/src/gui/painting/qoutlinemapper_p.h @@ -79,6 +79,8 @@ public: m_curve_threshold = scale == 0 ? qreal(0.25) : (qreal(0.25) / scale); } + void setClipRect(QRect clipRect); + void beginOutline(Qt::FillRule fillRule) { #ifdef QT_DEBUG_CONVERT @@ -163,6 +165,7 @@ public: QDataBuffer<int> m_contours; QRect m_clip_rect; + QRectF m_clip_trigger_rect; QRectF controlPointRect; // only valid after endOutline() QT_FT_Outline m_outline; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 1a2dbb6a9f..953999a292 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -407,13 +407,7 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) QRasterPaintEngineState *s = state(); ensureOutlineMapper(); - d->outlineMapper->m_clip_rect = d->deviceRect; - - if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT) - d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT); - if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT) - d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT); - + d->outlineMapper->setClipRect(d->deviceRect); d->rasterizer->setClipRect(d->deviceRect); s->penData.init(d->rasterBuffer.data(), this); |