diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-05-06 12:08:55 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-05-06 13:04:43 (GMT) |
commit | 3cec5ff3f0aa8d3eca0dfb325e83a8a3a18cb305 (patch) | |
tree | 9dea3f7f54657da451262f3a86af5a5385483d4c | |
parent | 4395513385ed639e54b1ebf5c0f1a919f9a9622b (diff) | |
download | Qt-3cec5ff3f0aa8d3eca0dfb325e83a8a3a18cb305.zip Qt-3cec5ff3f0aa8d3eca0dfb325e83a8a3a18cb305.tar.gz Qt-3cec5ff3f0aa8d3eca0dfb325e83a8a3a18cb305.tar.bz2 |
Prevented X server crash when calling XFillPolygon with >200000 points.
Don't know why the X server crashes, but it's reproducible both by us
and customers so we should fall back to the raster paint engine to avoid
the crash.
Task-number: 244362
Reviewed-by: Trond
-rw-r--r-- | src/gui/painting/qpaintengine_x11.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 4b2fbca..9cc9683 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1543,6 +1543,8 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p QX11PaintEnginePrivate::GCMode gcMode, QPaintEngine::PolygonDrawMode mode) { + Q_Q(QX11PaintEngine); + int clippedCount = 0; qt_float_point *clippedPoints = 0; @@ -1617,7 +1619,29 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p } else #endif if (fill.style() != Qt::NoBrush) { - if (clippedCount > 0) { + if (clippedCount > 200000) { + QPolygon poly; + for (int i = 0; i < clippedCount; ++i) + poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y)); + + const QRect bounds = poly.boundingRect(); + const QRect aligned = bounds + & QRect(QPoint(), QSize(pdev->width(), pdev->height())); + + QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied); + img.fill(0); + + QPainter painter(&img); + painter.translate(-aligned.x(), -aligned.y()); + painter.setPen(Qt::NoPen); + painter.setBrush(fill); + if (gcMode == BrushGC) + painter.setBrushOrigin(q->painter()->brushOrigin()); + painter.drawPolygon(poly); + painter.end(); + + q->drawImage(aligned, img, img.rect(), Qt::AutoColor); + } else if (clippedCount > 0) { QVarLengthArray<XPoint> xpoints(clippedCount); for (int i = 0; i < clippedCount; ++i) { xpoints[i].x = qFloor(clippedPoints[i].x); |