Mercurial > hg > svgui
changeset 1375:694004228ab7 zoom
Fix incorrect start/end overlay drawing when zoomed far in
author | Chris Cannam |
---|---|
date | Tue, 06 Nov 2018 10:51:46 +0000 |
parents | 631897ba9fca |
children | 5a051ca3170e |
files | layer/WaveformLayer.cpp layer/WaveformLayer.h view/Pane.cpp view/View.cpp view/View.h |
diffstat | 5 files changed, 66 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- 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; }
--- 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;
--- 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();
--- 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; }
--- 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;