JAL-2647 Added iterators and associated tests and benchmarks
[jalview.git] / src / jalview / appletgui / SeqCanvas.java
index 9de5452..20ec665 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
 {
@@ -113,12 +113,12 @@ public class SeqCanvas extends Panel implements ViewportListenerI
       {
         if (mstring != null)
         {
-          g.drawString(mstring, mpos * avcharWidth, ypos
-                  - (avcharHeight / 2));
+          g.drawString(mstring, mpos * avcharWidth,
+                  ypos - (avcharHeight / 2));
         }
-        g.drawLine((mpos * avcharWidth) + (avcharWidth / 2), (ypos + 2)
-                - (avcharHeight / 2), (mpos * avcharWidth)
-                + (avcharWidth / 2), ypos - 2);
+        g.drawLine((mpos * avcharWidth) + (avcharWidth / 2),
+                (ypos + 2) - (avcharHeight / 2),
+                (mpos * avcharWidth) + (avcharWidth / 2), ypos - 2);
       }
     }
   }
@@ -167,8 +167,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
       {
         int x = LABEL_WEST - fm.stringWidth(String.valueOf(value))
                 - avcharWidth / 2;
-        g.drawString(value + "", x, (ypos + (i * avcharHeight))
-                - (avcharHeight / 5));
+        g.drawString(value + "", x,
+                (ypos + (i * avcharHeight)) - (avcharHeight / 5));
       }
     }
   }
@@ -207,8 +207,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
 
       if (value != -1)
       {
-        g.drawString(String.valueOf(value), 0, (ypos + (i * avcharHeight))
-                - (avcharHeight / 5));
+        g.drawString(String.valueOf(value), 0,
+                (ypos + (i * avcharHeight)) - (avcharHeight / 5));
       }
     }
   }
@@ -237,14 +237,14 @@ public class SeqCanvas extends Panel implements ViewportListenerI
     lastsr = ranges.getStartRes();
 
     fastPaint = true;
-    gg.copyArea(horizontal * avcharWidth, vertical * avcharHeight, imgWidth
-            - horizontal * avcharWidth,
+    gg.copyArea(horizontal * avcharWidth, vertical * avcharHeight,
+            imgWidth - horizontal * avcharWidth,
             imgHeight - vertical * avcharHeight, -horizontal * avcharWidth,
             -vertical * avcharHeight);
 
-    int sr = ranges.getStartRes(), er = ranges.getEndRes(), ss = ranges
-            .getStartSeq(), es = ranges
-            .getEndSeq(), transX = 0, transY = 0;
+    int sr = ranges.getStartRes(), er = ranges.getEndRes(),
+            ss = ranges.getStartSeq(), es = ranges.getEndSeq(), transX = 0,
+            transY = 0;
 
     if (horizontal > 0) // scrollbar pulled right, image to the left
     {
@@ -261,7 +261,7 @@ public class SeqCanvas extends Panel implements ViewportListenerI
       ss = es - vertical;
       if (ss < ranges.getStartSeq()) // ie scrolling too fast, more than a page
                                      // at a
-                                 // time
+      // time
       {
         ss = ranges.getStartSeq();
       }
@@ -307,8 +307,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
   {
 
     if (img != null
-            && (fastPaint || (getSize().width != g.getClipBounds().width) || (getSize().height != g
-                    .getClipBounds().height)))
+            && (fastPaint || (getSize().width != g.getClipBounds().width)
+                    || (getSize().height != g.getClipBounds().height)))
     {
       g.drawImage(img, 0, 0, this);
       fastPaint = false;
@@ -491,22 +491,16 @@ 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;
-          }
-
-          gg.fillPolygon(new int[] { res * avcharWidth - avcharHeight / 4,
-              res * avcharWidth + avcharHeight / 4, res * avcharWidth },
-                  new int[] { ypos - (avcharHeight / 2),
-                      ypos - (avcharHeight / 2),
-                      ypos - (avcharHeight / 2) + 8 }, 3);
-
+          res = it.next() - startRes;
+          gg.fillPolygon(
+                  new int[]
+                  { res * avcharWidth - avcharHeight / 4, res * avcharWidth + avcharHeight / 4, res * avcharWidth },
+                  new int[]
+                  { ypos - (avcharHeight / 2), ypos - (avcharHeight / 2), ypos - (avcharHeight / 2) + 8 }, 3);
         }
       }
 
@@ -555,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())
@@ -565,8 +559,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
     }
     else
     {
-
       int screenY = 0;
+      final int screenYMax = endRes - startRes;
       int blockStart = startRes;
       int blockEnd = endRes;
 
@@ -584,33 +578,42 @@ public class SeqCanvas extends Panel implements ViewportListenerI
             continue;
           }
 
-          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(hideStart - 1, blockStart + screenYMax
+                  - screenY);
 
           g1.translate(screenY * avcharWidth, 0);
 
           draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
 
-          if (av.getShowHiddenMarkers())
+          /*
+           * draw the downline of the hidden column marker (ScalePanel draws the
+           * triangle on top) if we reached it
+           */
+          if (av.getShowHiddenMarkers() && blockEnd == hideStart - 1)
           {
             g1.setColor(Color.blue);
             g1.drawLine((blockEnd - blockStart + 1) * avcharWidth - 1,
-                    0 + offset, (blockEnd - blockStart + 1) * avcharWidth
-                            - 1, (endSeq - startSeq + 1) * avcharHeight
-                            + offset);
+                    0 + offset,
+                    (blockEnd - blockStart + 1) * avcharWidth - 1,
+                    (endSeq - startSeq + 1) * avcharHeight + offset);
           }
 
           g1.translate(-screenY * avcharWidth, 0);
           screenY += blockEnd - blockStart + 1;
           blockStart = hideEnd + 1;
 
-          if (screenY > (endRes - startRes))
+          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;
@@ -649,8 +652,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
 
       if (av.isShowSequenceFeatures())
       {
-        fr.drawSequence(g, nextSeq, startRes, endRes, offset
-                + ((i - startSeq) * avcharHeight), false);
+        fr.drawSequence(g, nextSeq, startRes, endRes,
+                offset + ((i - startSeq) * avcharHeight), false);
       }
 
       // / Highlight search Results once all sequences have been drawn
@@ -658,16 +661,15 @@ public class SeqCanvas extends Panel implements ViewportListenerI
       if (av.hasSearchResults())
       {
         int[] visibleResults = av.getSearchResults().getResults(nextSeq,
-                startRes,
-                endRes);
+                startRes, endRes);
         if (visibleResults != null)
         {
           for (int r = 0; r < visibleResults.length; r += 2)
           {
             sr.drawHighlightedText(nextSeq, visibleResults[r],
-                    visibleResults[r + 1], (visibleResults[r] - startRes)
-                            * avcharWidth, offset
-                            + ((i - startSeq) * avcharHeight));
+                    visibleResults[r + 1],
+                    (visibleResults[r] - startRes) * avcharWidth,
+                    offset + ((i - startSeq) * avcharHeight));
           }
         }
       }
@@ -723,7 +725,8 @@ public class SeqCanvas extends Panel implements ViewportListenerI
         {
           sx = (group.getStartRes() - startRes) * avcharWidth;
           sy = offset + ((i - startSeq) * avcharHeight);
-          ex = (((group.getEndRes() + 1) - group.getStartRes()) * avcharWidth) - 1;
+          ex = (((group.getEndRes() + 1) - group.getStartRes())
+                  * avcharWidth) - 1;
 
           if (sx + ex < 0 || sx > imgWidth)
           {
@@ -731,22 +734,20 @@ public class SeqCanvas extends Panel implements ViewportListenerI
           }
 
           if ((sx <= (endRes - startRes) * avcharWidth)
-                  && group.getSequences(null).contains(
-                          av.getAlignment().getSequenceAt(i)))
+                  && group.getSequences(null)
+                          .contains(av.getAlignment().getSequenceAt(i)))
           {
             if ((bottom == -1)
-                    && (i >= alHeight || !group.getSequences(null)
-                            .contains(
-                                    av.getAlignment().getSequenceAt(i + 1))))
+                    && (i >= alHeight || !group.getSequences(null).contains(
+                            av.getAlignment().getSequenceAt(i + 1))))
             {
               bottom = sy + avcharHeight;
             }
 
             if (!inGroup)
             {
-              if (((top == -1) && (i == 0))
-                      || !group.getSequences(null).contains(
-                              av.getAlignment().getSequenceAt(i - 1)))
+              if (((top == -1) && (i == 0)) || !group.getSequences(null)
+                      .contains(av.getAlignment().getSequenceAt(i - 1)))
               {
                 top = sy;
               }