JAL-2647 more iterators
[jalview.git] / src / jalview / appletgui / SeqCanvas.java
index 28c5291..8d429c7 100755 (executable)
@@ -37,7 +37,7 @@ import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.Panel;
 import java.beans.PropertyChangeEvent;
-import java.util.List;
+import java.util.Iterator;
 
 public class SeqCanvas extends Panel implements ViewportListenerI
 {
@@ -417,71 +417,71 @@ public class SeqCanvas extends Panel implements ViewportListenerI
           int canvasHeight, int startRes)
   {
     AlignmentI al = av.getAlignment();
-
+  
     FontMetrics fm = getFontMetrics(av.getFont());
-
+  
     LABEL_EAST = 0;
     LABEL_WEST = 0;
-
+  
     if (av.getScaleRightWrapped())
     {
       LABEL_EAST = fm.stringWidth(getMask());
     }
-
+  
     if (av.getScaleLeftWrapped())
     {
       LABEL_WEST = fm.stringWidth(getMask());
     }
-
+  
     int hgap = avcharHeight;
     if (av.getScaleAboveWrapped())
     {
       hgap += avcharHeight;
     }
-
+  
     int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / avcharWidth;
     int cHeight = av.getAlignment().getHeight() * avcharHeight;
-
+  
     av.setWrappedWidth(cWidth);
-
+  
     av.getRanges().setViewportStartAndWidth(startRes, cWidth);
-
+  
     int endx;
     int ypos = hgap;
-
+  
     int maxwidth = av.getAlignment().getWidth();
-
+  
     if (av.hasHiddenColumns())
     {
       maxwidth = av.getAlignment().getHiddenColumns()
               .findColumnPosition(maxwidth);
     }
-
+  
     while ((ypos <= canvasHeight) && (startRes < maxwidth))
     {
       endx = startRes + cWidth - 1;
-
+  
       if (endx > maxwidth)
       {
         endx = maxwidth;
       }
-
+  
       g.setColor(Color.black);
-
+  
       if (av.getScaleLeftWrapped())
       {
         drawWestScale(g, startRes, endx, ypos);
       }
-
+  
       if (av.getScaleRightWrapped())
       {
         g.translate(canvasWidth - LABEL_EAST, 0);
         drawEastScale(g, startRes, endx, ypos);
         g.translate(-(canvasWidth - LABEL_EAST), 0);
       }
-
+  
       g.translate(LABEL_WEST, 0);
-
+  
       if (av.getScaleAboveWrapped())
       {
         drawNorthScale(g, startRes, endx, ypos);
@@ -491,37 +491,27 @@ public class SeqCanvas extends Panel implements ViewportListenerI
         HiddenColumns hidden = av.getAlignment().getHiddenColumns();
         g.setColor(Color.blue);
         int res;
-        List<Integer> positions = hidden.findHiddenRegionPositions();
-        for (int pos : positions)
+        Iterator<Integer> it = hidden.getBoundedStartIterator(startRes,
+                endx + 1, true);
+        while (it.hasNext())
         {
-          res = pos - startRes;
-
-          if (res < 0 || res > endx - startRes)
-          {
-            continue;
-          }
-
+          res = it.next() - startRes;
           gg.fillPolygon(
                   new int[]
-                  { res * avcharWidth - avcharHeight / 4,
-                      res * avcharWidth + avcharHeight / 4,
-                      res * avcharWidth },
+                  { res * avcharWidth - avcharHeight / 4, res * avcharWidth + avcharHeight / 4, res * avcharWidth },
                   new int[]
-                  { ypos - (avcharHeight / 2), ypos - (avcharHeight / 2),
-                      ypos - (avcharHeight / 2) + 8 },
-                  3);
-
+                  { ypos - (avcharHeight / 2), ypos - (avcharHeight / 2), ypos - (avcharHeight / 2) + 8 }, 3);
         }
       }
-
+  
       if (g.getClip() == null)
       {
         g.setClip(0, 0, cWidth * avcharWidth, canvasHeight);
       }
-
+  
       drawPanel(g, startRes, endx, 0, al.getHeight() - 1, ypos);
       g.setClip(null);
-
+  
       if (av.isShowAnnotation())
       {
         g.translate(0, cHeight + ypos + 4);
@@ -529,17 +519,17 @@ public class SeqCanvas extends Panel implements ViewportListenerI
         {
           annotations = new AnnotationPanel(av);
         }
-
+  
         annotations.drawComponent(g, startRes, endx + 1);
         g.translate(0, -cHeight - ypos - 4);
       }
       g.translate(-LABEL_WEST, 0);
-
+  
       ypos += cHeight + getAnnotationHeight() + hgap;
-
+  
       startRes += cWidth;
     }
-
+  
   }
 
   AnnotationPanel annotations;
@@ -559,8 +549,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
     return annotations.adjustPanelHeight();
   }
 
-  private void drawPanel(Graphics g1, int startRes, int endRes,
-          int startSeq, int endSeq, int offset)
+  private void drawPanel(Graphics g1, final int startRes, final int endRes,
+          final int startSeq, final int endSeq, final int offset)
   {
 
     if (!av.hasHiddenColumns())
@@ -569,52 +559,52 @@ public class SeqCanvas extends Panel implements ViewportListenerI
     }
     else
     {
-
       int screenY = 0;
+      final int screenYMax = endRes - startRes;
       int blockStart = startRes;
       int blockEnd = endRes;
 
-      if (av.hasHiddenColumns())
+      HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+      Iterator<int[]> regions = hidden.getBoundedVisRegionIterator(startRes,
+              endRes);
+      while (regions.hasNext())
       {
-        HiddenColumns hidden = av.getAlignment().getHiddenColumns();
-        for (int[] region : hidden.getHiddenColumnsCopy())
-        {
-          int hideStart = region[0];
-          int hideEnd = region[1];
+        int[] region = regions.next();
 
-          if (hideStart <= blockStart)
-          {
-            blockStart += (hideEnd - hideStart) + 1;
-            continue;
-          }
+        blockStart = region[0];
 
-          blockEnd = hideStart - 1;
+        /*
+         * draw up to just before the next hidden region, or the end of
+         * the visible region, whichever comes first
+         */
+        blockEnd = Math.min(region[1], blockStart + screenYMax - screenY);
 
-          g1.translate(screenY * avcharWidth, 0);
+        g1.translate(screenY * avcharWidth, 0);
 
-          draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+        draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
 
-          if (av.getShowHiddenMarkers())
-          {
-            g1.setColor(Color.blue);
-            g1.drawLine((blockEnd - blockStart + 1) * avcharWidth - 1,
-                    0 + offset,
-                    (blockEnd - blockStart + 1) * avcharWidth - 1,
-                    (endSeq - startSeq + 1) * avcharHeight + offset);
-          }
+        /*
+         * draw the downline of the hidden column marker (ScalePanel draws the
+         * triangle on top) if we reached it
+         */
+        if (av.getShowHiddenMarkers() && blockEnd == region[1])
+        {
+          g1.setColor(Color.blue);
+          g1.drawLine((blockEnd - blockStart + 1) * avcharWidth - 1,
+                  0 + offset, (blockEnd - blockStart + 1) * avcharWidth - 1,
+                  (endSeq - startSeq + 1) * avcharHeight + offset);
+        }
 
-          g1.translate(-screenY * avcharWidth, 0);
-          screenY += blockEnd - blockStart + 1;
-          blockStart = hideEnd + 1;
+        g1.translate(-screenY * avcharWidth, 0);
+        screenY += blockEnd - blockStart + 1;
 
-          if (screenY > (endRes - startRes))
-          {
-            // already rendered last block
-            return;
-          }
+        if (screenY > screenYMax)
+        {
+          // already rendered last block
+          return;
         }
       }
-      if (screenY <= (endRes - startRes))
+      if (screenY <= screenYMax)
       {
         // remaining visible region to render
         blockEnd = blockStart + (endRes - startRes) - screenY;