diff --git a/src/areachart/areachartitem.cpp b/src/areachart/areachartitem.cpp index 8b04084..adb540d 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 0c517df..1355867 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 200eda8..89a991e 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 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 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 11f9ac9..fc42f52 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(); + } } /*!