# HG changeset patch # User Chris Cannam # Date 1541501506 0 # Node ID 694004228ab7d5f7f2ba0fbd26841d62e44f00f2 # Parent 631897ba9fcab50b5138c3d7dad4b07797081cf9 Fix incorrect start/end overlay drawing when zoomed far in diff -r 631897ba9fca -r 694004228ab7 layer/WaveformLayer.cpp --- a/layer/WaveformLayer.cpp Tue Nov 06 08:59:03 2018 +0000 +++ b/layer/WaveformLayer.cpp Tue Nov 06 10:51:46 2018 +0000 @@ -826,7 +826,8 @@ } if (f0 < frame0) { - SVCERR << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl; + // Not an error, this simply occurs when painting the + // start of a signal in PixelsPerFrame zone continue; } diff -r 631897ba9fca -r 694004228ab7 layer/WaveformLayer.h --- a/layer/WaveformLayer.h Tue Nov 06 08:59:03 2018 +0000 +++ b/layer/WaveformLayer.h Tue Nov 06 10:51:46 2018 +0000 @@ -20,6 +20,8 @@ #include "SingleColourLayer.h" +#include "base/ZoomLevel.h" + #include "data/model/RangeSummarisableTimeValueModel.h" class View; diff -r 631897ba9fca -r 694004228ab7 view/Pane.cpp --- a/view/Pane.cpp Tue Nov 06 08:59:03 2018 +0000 +++ b/view/Pane.cpp Tue Nov 06 10:51:46 2018 +0000 @@ -750,11 +750,8 @@ void Pane::drawModelTimeExtents(QRect r, QPainter &paint, const Model *model) { - int x0 = getXForFrame(model->getStartFrame()); - int x1 = getXForFrame(model->getEndFrame()); - paint.save(); - + QBrush brush; if (hasLightBackground()) { @@ -765,14 +762,24 @@ paint.setPen(Qt::white); } - if (x0 > r.x()) { - paint.fillRect(0, 0, x0, height(), brush); - paint.drawLine(x0, 0, x0, height()); + sv_frame_t f0 = model->getStartFrame(); + + if (f0 > getStartFrame() && f0 < getEndFrame()) { + int x0 = getXForFrame(f0); + if (x0 > r.x()) { + paint.fillRect(0, 0, x0, height(), brush); + paint.drawLine(x0, 0, x0, height()); + } } - if (x1 < r.x() + r.width()) { - paint.fillRect(x1, 0, width() - x1, height(), brush); - paint.drawLine(x1, 0, x1, height()); + sv_frame_t f1 = model->getEndFrame(); + + if (f1 > getStartFrame() && f1 < getEndFrame()) { + int x1 = getXForFrame(f1); + if (x1 < r.x() + r.width()) { + paint.fillRect(x1, 0, width() - x1, height(), brush); + paint.drawLine(x1, 0, x1, height()); + } } paint.restore(); diff -r 631897ba9fca -r 694004228ab7 view/View.cpp --- a/view/View.cpp Tue Nov 06 08:59:03 2018 +0000 +++ b/view/View.cpp Tue Nov 06 10:51:46 2018 +0000 @@ -395,18 +395,50 @@ sv_frame_t level = m_zoomLevel.level; sv_frame_t fdiff = frame - getCentreFrame(); - int diff, result; - + int result = 0; + + bool inRange = false; if (m_zoomLevel.zone == ZoomLevel::FramesPerPixel) { - diff = int(fdiff / level); - if ((fdiff < 0) && ((fdiff % level) != 0)) { - --diff; // round to the left + inRange = ((fdiff / level) < sv_frame_t(INT_MAX) && + (fdiff / level) > sv_frame_t(INT_MIN)); + } else { + inRange = (fdiff < sv_frame_t(INT_MAX) / level && + fdiff > sv_frame_t(INT_MIN) / level); + } + + if (inRange) { + + sv_frame_t adjusted; + + if (m_zoomLevel.zone == ZoomLevel::FramesPerPixel) { + adjusted = fdiff / level; + if ((fdiff < 0) && ((fdiff % level) != 0)) { + --adjusted; // round to the left + } + } else { + adjusted = fdiff * level; } - } else { - diff = int(fdiff * level); + + adjusted = adjusted + (width()/2); + + if (adjusted > INT_MAX || adjusted < INT_MIN) { + inRange = false; + } else { + result = int(adjusted); + } } - result = int(diff + (width()/2)); + if (!inRange) { + SVCERR << "ERROR: Frame " << frame + << " is out of range in View::getXForFrame" << endl; + SVCERR << "ERROR: (centre frame = " << getCentreFrame() << ", fdiff = " + << fdiff << ", zoom level = " << m_zoomLevel << ")" << endl; + SVCERR << "ERROR: This is a logic error: getXForFrame should not be " + << "called for locations unadjacent to the current view" + << endl; + return 0; + } + return result; } diff -r 631897ba9fca -r 694004228ab7 view/View.h --- a/view/View.h Tue Nov 06 08:59:03 2018 +0000 +++ b/view/View.h Tue Nov 06 10:51:46 2018 +0000 @@ -104,7 +104,11 @@ /** * Return the pixel x-coordinate corresponding to a given sample - * frame (which may be negative). + * frame. The frame is permitted to be negative, and the result + * may be outside the currently visible area. But this should not + * be called with frame values very far away from the currently + * visible area, as that could lead to overflow. In that situation + * an error will be logged and 0 returned. */ int getXForFrame(sv_frame_t frame) const;