summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTitta Heikkala <titta.heikkala@digia.com>2013-08-23 12:38:29 +0300
committerTitta Heikkala <titta.heikkala@digia.com>2013-08-26 12:07:10 +0300
commit1e4c29e111d4c5a2344f7370c399625c565ba72c (patch)
tree35a758319b5a65ca020c64002d6bb0b51b55976e /src
parent2e0922f74ba527c2ee6d9226e15f5baf0f6ae4b5 (diff)
Fix zooming in crash
The bounding rect has to fit inside int limits when zooming in, meaning that the height and width both have to be within the int limits (INT_MAX). QWidget::update() uses a region (based on bounding rect) that has to be compatible with QRect. The geometry change is only done if the bounding rect fulfills this requirement. Task-number: QTRD-1907 Change-Id: I4e874de355390c5fc983ac1e0976bf0d21e2d10c Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/areachart/areachartitem.cpp14
-rw-r--r--src/linechart/linechartitem.cpp23
-rw-r--r--src/scatterchart/scatterchartitem.cpp53
-rw-r--r--src/splinechart/splinechartitem.cpp17
4 files changed, 70 insertions, 37 deletions
diff --git a/src/areachart/areachartitem.cpp b/src/areachart/areachartitem.cpp
index 8b04084d..adb540d8 100644
--- a/src/areachart/areachartitem.cpp
+++ b/src/areachart/areachartitem.cpp
@@ -110,10 +110,16 @@ void AreaChartItem::updatePath()
}
}
path.closeSubpath();
- prepareGeometryChange();
- m_path = path;
- m_rect = path.boundingRect();
- update();
+
+ // Only zoom in if the bounding rect of the path fits inside int limits. QWidget::update() uses
+ // a region that has to be compatible with QRect.
+ if (path.boundingRect().height() <= INT_MAX
+ && path.boundingRect().width() <= INT_MAX) {
+ prepareGeometryChange();
+ m_path = path;
+ m_rect = path.boundingRect();
+ update();
+ }
}
void AreaChartItem::handleUpdated()
diff --git a/src/linechart/linechartitem.cpp b/src/linechart/linechartitem.cpp
index 0c517df6..13558671 100644
--- a/src/linechart/linechartitem.cpp
+++ b/src/linechart/linechartitem.cpp
@@ -276,13 +276,26 @@ void LineChartItem::updateGeometry()
stroker.setCapStyle(Qt::SquareCap);
stroker.setMiterLimit(m_linePen.miterLimit());
- prepareGeometryChange();
+ QPainterPath checkShapePath = stroker.createStroke(fullPath);
+
+ // Only zoom in if the bounding rects of the paths fit inside int limits. QWidget::update() uses
+ // a region that has to be compatible with QRect.
+ if (checkShapePath.boundingRect().height() <= INT_MAX
+ && checkShapePath.boundingRect().width() <= INT_MAX
+ && linePath.boundingRect().height() <= INT_MAX
+ && linePath.boundingRect().width() <= INT_MAX
+ && fullPath.boundingRect().height() <= INT_MAX
+ && fullPath.boundingRect().width() <= INT_MAX) {
+ prepareGeometryChange();
- m_linePath = linePath;
- m_fullPath = fullPath;
- m_shapePath = stroker.createStroke(fullPath);
+ m_linePath = linePath;
+ m_fullPath = fullPath;
+ m_shapePath = checkShapePath;
- m_rect = m_shapePath.boundingRect();
+ m_rect = m_shapePath.boundingRect();
+ } else {
+ update();
+ }
}
void LineChartItem::handleUpdated()
diff --git a/src/scatterchart/scatterchartitem.cpp b/src/scatterchart/scatterchartitem.cpp
index 200eda82..89a991e3 100644
--- a/src/scatterchart/scatterchartitem.cpp
+++ b/src/scatterchart/scatterchartitem.cpp
@@ -126,31 +126,36 @@ void ScatterChartItem::updateGeometry()
QRectF clipRect(QPointF(0,0),domain()->size());
- QVector<bool> offGridStatus = offGridStatusVector();
- const int seriesLastIndex = m_series->count() - 1;
-
- for (int i = 0; i < points.size(); i++) {
- QGraphicsItem *item = items.at(i);
- const QPointF &point = points.at(i);
- const QRectF &rect = item->boundingRect();
- // During remove animation series may have different number of points,
- // so ensure we don't go over the index. Animation handling itself ensures that
- // if there is actually no points in the series, then it won't generate a fake point,
- // so we can be assured there is always at least one point in m_series here.
- // Note that marker map values can be technically incorrect during the animation,
- // if it was caused by an insert, but this shouldn't be a problem as the points are
- // fake anyway. After remove animation stops, geometry is updated to correct one.
- m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i));
- item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
-
- if (!m_visible || offGridStatus.at(i))
- item->setVisible(false);
- else
- item->setVisible(true);
- }
+ // Only zoom in if the clipRect fits inside int limits. QWidget::update() uses
+ // a region that has to be compatible with QRect.
+ if (clipRect.height() <= INT_MAX
+ && clipRect.width() <= INT_MAX) {
+ QVector<bool> offGridStatus = offGridStatusVector();
+ const int seriesLastIndex = m_series->count() - 1;
+
+ for (int i = 0; i < points.size(); i++) {
+ QGraphicsItem *item = items.at(i);
+ const QPointF &point = points.at(i);
+ const QRectF &rect = item->boundingRect();
+ // During remove animation series may have different number of points,
+ // so ensure we don't go over the index. Animation handling itself ensures that
+ // if there is actually no points in the series, then it won't generate a fake point,
+ // so we can be assured there is always at least one point in m_series here.
+ // Note that marker map values can be technically incorrect during the animation,
+ // if it was caused by an insert, but this shouldn't be a problem as the points are
+ // fake anyway. After remove animation stops, geometry is updated to correct one.
+ m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i));
+ item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
+
+ if (!m_visible || offGridStatus.at(i))
+ item->setVisible(false);
+ else
+ item->setVisible(true);
+ }
- prepareGeometryChange();
- m_rect = clipRect;
+ prepareGeometryChange();
+ m_rect = clipRect;
+ }
}
void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
diff --git a/src/splinechart/splinechartitem.cpp b/src/splinechart/splinechartitem.cpp
index 11f9ac9b..fc42f529 100644
--- a/src/splinechart/splinechartitem.cpp
+++ b/src/splinechart/splinechartitem.cpp
@@ -267,7 +267,6 @@ void SplineChartItem::updateGeometry()
}
fullPath = splinePath;
}
- m_path = splinePath;
QPainterPathStroker stroker;
// The full path is comprised of three separate paths.
@@ -278,10 +277,20 @@ void SplineChartItem::updateGeometry()
stroker.setCapStyle(Qt::SquareCap);
stroker.setMiterLimit(m_linePen.miterLimit());
- prepareGeometryChange();
+ // Only zoom in if the bounding rects of the path fit inside int limits. QWidget::update() uses
+ // a region that has to be compatible with QRect.
+ QPainterPath checkShapePath = stroker.createStroke(fullPath);
+ if (checkShapePath.boundingRect().height() <= INT_MAX
+ && checkShapePath.boundingRect().width() <= INT_MAX
+ && splinePath.boundingRect().height() <= INT_MAX
+ && splinePath.boundingRect().width() <= INT_MAX) {
+ m_path = splinePath;
- m_fullPath = stroker.createStroke(fullPath);
- m_rect = m_fullPath.boundingRect();
+ prepareGeometryChange();
+
+ m_fullPath = checkShapePath;
+ m_rect = m_fullPath.boundingRect();
+ }
}
/*!