summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-05-06 12:08:55 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-05-06 13:04:43 (GMT)
commit3cec5ff3f0aa8d3eca0dfb325e83a8a3a18cb305 (patch)
tree9dea3f7f54657da451262f3a86af5a5385483d4c
parent4395513385ed639e54b1ebf5c0f1a919f9a9622b (diff)
downloadQt-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.cpp26
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);