changeset 389:2ed4e572d0d4

* Attempt fix for #1914752 export image has holes (1.0 and 1.2)
author Chris Cannam
date Tue, 20 May 2008 10:40:20 +0000
parents 881470f9ca48
children 0384cf63e91c
files layer/Layer.h layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h view/Overview.cpp view/View.cpp
diffstat 5 files changed, 98 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- 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
     };
--- 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();
 }
--- 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;
--- 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;
                 }
             }
--- 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();
 	}
     }