# HG changeset patch # User Chris Cannam # Date 1211280020 0 # Node ID 2ed4e572d0d440e967a508865331351195ce761d # Parent 881470f9ca48e68116668a4b483360a9aa22a94b * Attempt fix for #1914752 export image has holes (1.0 and 1.2) diff -r 881470f9ca48 -r 2ed4e572d0d4 layer/Layer.h --- a/layer/Layer.h Tue May 20 08:37:46 2008 +0000 +++ b/layer/Layer.h Tue May 20 10:40:20 2008 +0000 @@ -76,8 +76,29 @@ */ virtual bool supportsOtherZoomLevels() const { return true; } + /** + * Paint the given rectangle of this layer onto the given view + * using the given painter, superimposing it on top of any + * existing material in that view. The view is provided here + * because it is possible for one layer to exist in more than one + * view, so the dimensions of the view may vary from one paint + * call to another (without any view having been resized). + */ virtual void paint(View *, QPainter &, QRect) const = 0; + /** + * Enable or disable synchronous painting. If synchronous + * painting is enabled, a call to paint() must complete painting + * the entire rectangle before it returns. If synchronous + * painting is disabled (which should be the default), the paint() + * call may defer painting some regions if data is not yet + * available, by calling back on its view to schedule another + * update. Synchronous painting is necessary when rendering to an + * image. Simple layer types will always paint synchronously, and + * so may ignore this. + */ + virtual void setSynchronousPainting(bool /* synchronous */) { } + enum VerticalPosition { PositionTop, PositionMiddle, PositionBottom }; diff -r 881470f9ca48 -r 2ed4e572d0d4 layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Tue May 20 08:37:46 2008 +0000 +++ b/layer/SpectrogramLayer.cpp Tue May 20 10:40:20 2008 +0000 @@ -68,6 +68,7 @@ m_normalizeColumns(false), m_normalizeVisibleArea(false), m_lastEmittedZoomStep(-1), + m_synchronous(true), //!!! m_lastPaintBlockWidth(0), m_updateTimer(0), m_candidateFillStartFrame(0), @@ -1672,6 +1673,12 @@ } void +SpectrogramLayer::setSynchronousPainting(bool synchronous) +{ + m_synchronous = synchronous; +} + +void SpectrogramLayer::paint(View *v, QPainter &paint, QRect rect) const { // What a lovely, old-fashioned function this is. @@ -1883,24 +1890,31 @@ int paintBlockWidth = m_lastPaintBlockWidth; - if (paintBlockWidth == 0) { - paintBlockWidth = (300000 / zoomLevel); + if (m_synchronous) { + if (paintBlockWidth < x1 - x0) { + // always paint full width + paintBlockWidth = x1 - x0; + } } else { - RealTime lastTime = m_lastPaintTime; - while (lastTime > RealTime::fromMilliseconds(200) && - paintBlockWidth > 50) { - paintBlockWidth /= 2; - lastTime = lastTime / 2; + if (paintBlockWidth == 0) { + paintBlockWidth = (300000 / zoomLevel); + } else { + RealTime lastTime = m_lastPaintTime; + while (lastTime > RealTime::fromMilliseconds(200) && + paintBlockWidth > 50) { + paintBlockWidth /= 2; + lastTime = lastTime / 2; + } + while (lastTime < RealTime::fromMilliseconds(90) && + paintBlockWidth < 1500) { + paintBlockWidth *= 2; + lastTime = lastTime * 2; + } } - while (lastTime < RealTime::fromMilliseconds(90) && - paintBlockWidth < 1500) { - paintBlockWidth *= 2; - lastTime = lastTime * 2; - } + + if (paintBlockWidth < 20) paintBlockWidth = 20; } - if (paintBlockWidth < 20) paintBlockWidth = 20; - #ifdef DEBUG_SPECTROGRAM_REPAINT std::cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << std::endl; #endif @@ -2128,13 +2142,14 @@ for (int s = s0i; s <= s1i; ++s) { - if (!fft->isColumnAvailable(s)) { + if (!m_synchronous) { + if (!fft->isColumnAvailable(s)) { #ifdef DEBUG_SPECTROGRAM_REPAINT - std::cerr << "Met unavailable column at col " << s << std::endl; + std::cerr << "Met unavailable column at col " << s << std::endl; #endif -// continue; - runOutOfData = true; - break; + runOutOfData = true; + break; + } } if (!fftSuspended) { @@ -2379,37 +2394,40 @@ cache.startFrame = startFrame; cache.zoomLevel = zoomLevel; - if (!m_normalizeVisibleArea || !overallMagChanged) { + if (!m_synchronous) { + + if (!m_normalizeVisibleArea || !overallMagChanged) { - if (cache.validArea.x() > 0) { + if (cache.validArea.x() > 0) { #ifdef DEBUG_SPECTROGRAM_REPAINT - std::cerr << "SpectrogramLayer::paint() updating left (0, " - << cache.validArea.x() << ")" << std::endl; + std::cerr << "SpectrogramLayer::paint() updating left (0, " + << cache.validArea.x() << ")" << std::endl; #endif - v->update(0, 0, cache.validArea.x(), h); + v->update(0, 0, cache.validArea.x(), h); + } + + if (cache.validArea.x() + cache.validArea.width() < + cache.pixmap.width()) { +#ifdef DEBUG_SPECTROGRAM_REPAINT + std::cerr << "SpectrogramLayer::paint() updating right (" + << cache.validArea.x() + cache.validArea.width() + << ", " + << cache.pixmap.width() - (cache.validArea.x() + + cache.validArea.width()) + << ")" << std::endl; +#endif + v->update(cache.validArea.x() + cache.validArea.width(), + 0, + cache.pixmap.width() - (cache.validArea.x() + + cache.validArea.width()), + h); + } + } else { + // overallMagChanged + std::cerr << "\noverallMagChanged - updating all\n" << std::endl; + cache.validArea = QRect(); + v->update(); } - - if (cache.validArea.x() + cache.validArea.width() < - cache.pixmap.width()) { -#ifdef DEBUG_SPECTROGRAM_REPAINT - std::cerr << "SpectrogramLayer::paint() updating right (" - << cache.validArea.x() + cache.validArea.width() - << ", " - << cache.pixmap.width() - (cache.validArea.x() + - cache.validArea.width()) - << ")" << std::endl; -#endif - v->update(cache.validArea.x() + cache.validArea.width(), - 0, - cache.pixmap.width() - (cache.validArea.x() + - cache.validArea.width()), - h); - } - } else { - // overallMagChanged - std::cerr << "\noverallMagChanged - updating all\n" << std::endl; - cache.validArea = QRect(); - v->update(); } illuminateLocalFeatures(v, paint); @@ -2418,9 +2436,11 @@ std::cerr << "SpectrogramLayer::paint() returning" << std::endl; #endif - m_lastPaintBlockWidth = paintBlockWidth; - (void)gettimeofday(&tv, 0); - m_lastPaintTime = RealTime::fromTimeval(tv) - mainPaintStart; + if (!m_synchronous) { + m_lastPaintBlockWidth = paintBlockWidth; + (void)gettimeofday(&tv, 0); + m_lastPaintTime = RealTime::fromTimeval(tv) - mainPaintStart; + } if (fftSuspended) fft->resume(); } diff -r 881470f9ca48 -r 2ed4e572d0d4 layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Tue May 20 08:37:46 2008 +0000 +++ b/layer/SpectrogramLayer.h Tue May 20 10:40:20 2008 +0000 @@ -57,6 +57,7 @@ virtual const ZoomConstraint *getZoomConstraint() const { return this; } virtual const Model *getModel() const { return m_model; } virtual void paint(View *v, QPainter &paint, QRect rect) const; + virtual void setSynchronousPainting(bool synchronous); virtual int getVerticalScaleWidth(View *v, QPainter &) const; virtual void paintVerticalScale(View *v, QPainter &paint, QRect rect) const; @@ -258,6 +259,7 @@ bool m_normalizeColumns; bool m_normalizeVisibleArea; int m_lastEmittedZoomStep; + bool m_synchronous; mutable int m_lastPaintBlockWidth; mutable RealTime m_lastPaintTime; diff -r 881470f9ca48 -r 2ed4e572d0d4 view/Overview.cpp --- a/view/Overview.cpp Tue May 20 08:37:46 2008 +0000 +++ b/view/Overview.cpp Tue May 20 10:40:20 2008 +0000 @@ -55,8 +55,8 @@ for (LayerList::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) { if ((*i)->getModel() && - !(*i)->getModel()->isOK() || - !(*i)->getModel()->isReady()) { + (!(*i)->getModel()->isOK() || + !(*i)->getModel()->isReady())) { return; } } diff -r 881470f9ca48 -r 2ed4e572d0d4 view/View.cpp --- a/view/View.cpp Tue May 20 08:37:46 2008 +0000 +++ b/view/View.cpp Tue May 20 10:40:20 2008 +0000 @@ -2206,8 +2206,12 @@ std::cerr << "Centre frame now: " << m_centreFrame << " drawing to " << chunk.x() + x + xorigin << ", " << chunk.width() << std::endl; + (*i)->setSynchronousPainting(true); + (*i)->paint(this, paint, chunk); + (*i)->setSynchronousPainting(false); + paint.restore(); } }