Merge branch 'develop' into develop_m2_8_1_2
[jalview.git] / src / jalview / renderer / AnnotationRenderer.java
index 64ab859..6d00118 100644 (file)
@@ -35,16 +35,29 @@ import java.awt.Image;
 import java.awt.font.LineMetrics;
 import java.awt.geom.AffineTransform;
 import java.awt.image.ImageObserver;
+import java.util.BitSet;
 import java.util.Hashtable;
 
 import com.stevesoft.pat.Regex;
 
 public class AnnotationRenderer
 {
+  /**
+   * flag indicating if timing and redraw parameter info should be output
+   */
+  private final boolean debugRedraw;
 
   public AnnotationRenderer()
   {
-    // TODO Auto-generated constructor stub
+    this(false);
+  }
+  /**
+   * Create a new annotation Renderer
+   * @param debugRedraw flag indicating if timing and redraw parameter info should be output
+   */
+  public AnnotationRenderer(boolean debugRedraw)
+  {
+    this.debugRedraw=debugRedraw;
   }
 
   public void drawStemAnnot(Graphics g, Annotation[] row_annotations,
@@ -143,6 +156,22 @@ public class AnnotationRenderer
    * width of image to render in panel
    */
   private int imgWidth;
+  /**
+   * offset to beginning of visible area
+   */
+  private int sOffset;
+  /**
+   * offset to end of visible area
+   */
+  private int visHeight;
+  /**
+   * indicate if the renderer should only render the visible portion of the annotation given the current view settings
+   */
+  private boolean useClip=true;
+  /**
+   * master flag indicating if renderer should ever try to clip. not enabled for jalview 2.8.1 
+   */
+  private boolean canClip=false;
 
   
   public void drawPseudoNode(Graphics g, Color nonCanColor, Annotation[] row_annotations,
@@ -212,6 +241,22 @@ public class AnnotationRenderer
     annotationPanel = annotPanel;
     fadedImage = annotPanel.getFadedImage();
     imgWidth = annotPanel.getFadedImageWidth();
+    // visible area for rendering
+    int[] bounds=annotPanel.getVisibleVRange();
+    if (bounds!=null)
+    {
+      sOffset = bounds[0];
+      visHeight = bounds[1];
+      if (visHeight==0)
+      {
+        useClip=false;
+      } else {
+        useClip=canClip;
+      }
+    } else {
+      useClip=false;
+    }
+
     updateFromAlignViewport(av);
   }
 
@@ -311,6 +356,7 @@ public class AnnotationRenderer
           AlignViewportI av, Graphics g, int activeRow, int startRes,
           int endRes)
   {
+    long stime=System.currentTimeMillis();
     boolean usedFaded = false;
     // NOTES:
     // AnnotationPanel needs to implement: ImageObserver, access to
@@ -334,12 +380,16 @@ public class AnnotationRenderer
     boolean centreColLabels, centreColLabelsDef = av
             .getCentreColumnLabels();
     boolean scaleColLabel = false;
-    boolean[] graphGroupDrawn = new boolean[aa.length];
+
+    BitSet graphGroupDrawn = new BitSet();
     int charOffset = 0; // offset for a label
     float fmWidth, fmScaling = 1f; // scaling for a label to fit it into a
     // column.
     Font ofont = g.getFont();
     // \u03B2 \u03B1
+    // debug ints
+    int yfrom=0,f_i=0,yto=0,f_to=0;
+    boolean clipst=false,clipend=false;
     for (int i = 0; i < aa.length; i++)
     {
       AlignmentAnnotation row = aa[i];
@@ -353,10 +403,20 @@ public class AnnotationRenderer
       scaleColLabel = row.scaleColLabel;
       lastSS = ' ';
       lastSSX = 0;
+      
+      if (!useClip || ((y-charHeight)<visHeight && (y+row.height+charHeight*2)>=sOffset)) 
+      {// if_in_visible_region
+        if (!clipst)
+        {
+          clipst=true;
+          yfrom=y;
+          f_i=i;
+        }
+        yto = y;
+        f_to=i;
       if (row.graph > 0)
       {
-        if (row.graphGroup > -1 && graphGroupDrawn[row.graphGroup])
-        {
+        if (row.graphGroup > -1 && graphGroupDrawn.get(row.graphGroup)) {
           continue;
         }
 
@@ -817,8 +877,9 @@ public class AnnotationRenderer
       {
         if (row.graph == AlignmentAnnotation.LINE_GRAPH)
         {
-          if (row.graphGroup > -1 && !graphGroupDrawn[row.graphGroup])
+          if (row.graphGroup > -1 && !graphGroupDrawn.get(row.graphGroup))
           {
+            // TODO: JAL-1291 revise rendering model so the graphGroup map is computed efficiently for all visible labels
             float groupmax = -999999, groupmin = 9999999;
             for (int gg = 0; gg < aa.length; gg++)
             {
@@ -851,7 +912,7 @@ public class AnnotationRenderer
               }
             }
 
-            graphGroupDrawn[row.graphGroup] = true;
+            graphGroupDrawn.set(row.graphGroup);
           }
           else
           {
@@ -865,7 +926,12 @@ public class AnnotationRenderer
                   row.graphMax, y);
         }
       }
-
+    } else {
+      if (clipst && !clipend)
+      {
+        clipend = true;
+      }
+    }// end if_in_visible_region
       if (row.graph > 0 && row.hasText)
       {
         y += charHeight;
@@ -876,6 +942,27 @@ public class AnnotationRenderer
         y += aa[i].height;
       }
     }
+    if (debugRedraw)
+    {
+      if (canClip)
+      {
+        if (clipst)
+        {
+          System.err.println("Start clip at : " + yfrom + " (index " + f_i
+                  + ")");
+        }
+        if (clipend)
+        {
+          System.err.println("End clip at : " + yto + " (index " + f_to
+                  + ")");
+        }
+      }
+      ;
+      System.err.println("Annotation Rendering time:"
+              + (System.currentTimeMillis() - stime));
+    }
+    ;
+
     return !usedFaded;
   }