JAL-3210 Improvements to eclipse detection. New src tree and SwingJS updated from...
[jalview.git] / src / jalview / renderer / seqfeatures / FeatureColourFinder.java
index 0c18d39..8da880a 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.renderer.seqfeatures;
 
 import jalview.api.FeatureRenderer;
@@ -28,6 +48,8 @@ public class FeatureColourFinder
    */
   private BufferedImage offscreenImage;
 
+  private Graphics goff;
+
   /**
    * Constructor
    * 
@@ -37,6 +59,7 @@ public class FeatureColourFinder
   {
     featureRenderer = fr;
     offscreenImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+    goff = offscreenImage.getGraphics();
   }
 
   /**
@@ -47,27 +70,25 @@ public class FeatureColourFinder
    * transparency, this class provides a dummy 'offscreen' graphics context
    * where multiple feature colours can be overlaid and the combined colour read
    * back.
+   * <p>
+   * This method is not thread-safe when transparency is applied, since a shared
+   * BufferedImage would be used by all threads to hold the composite colour at
+   * a position. Each thread should use a separate instance of this class.
    * 
    * @param defaultColour
    * @param seq
    * @param column
-   *          alignment column position (base zero)
+   *          alignment column position (0..)
    * @return
    */
   public Color findFeatureColour(Color defaultColour, SequenceI seq,
           int column)
   {
-    if (!((FeatureRendererModel) featureRenderer).hasRenderOrder())
+    if (noFeaturesDisplayed())
     {
       return defaultColour;
     }
 
-    FeaturesDisplayedI displayed = featureRenderer.getFeaturesDisplayed();
-    if (displayed == null || displayed.getVisibleFeatureCount() == 0)
-    {
-      return defaultColour; // nothing to see here folks
-    }
-
     Graphics g = null;
 
     /*
@@ -76,14 +97,14 @@ public class FeatureColourFinder
      */
     if (featureRenderer.getTransparency() != 1f)
     {
-      g = offscreenImage.getGraphics();
+      g = goff;
       if (defaultColour != null)
       {
         offscreenImage.setRGB(0, 0, defaultColour.getRGB());
       }
     }
 
-    Color c = featureRenderer.findFeatureColour(seq, column, g);
+    Color c = featureRenderer.findFeatureColour(seq, column + 1, g);
     if (c == null)
     {
       return defaultColour;
@@ -95,4 +116,67 @@ public class FeatureColourFinder
     }
     return c;
   }
+
+  public int findFeatureColourInt(int defaultColour, SequenceI seq,
+          int column)
+  {
+    // if (noFeaturesDisplayed())
+    // {
+    // return defaultColour;
+    // }
+
+    Graphics g = null;
+
+    /*
+     * if transparency applies, provide a notional 1x1 graphics context 
+     * that has been primed with the default colour
+     */
+    if (featureRenderer.getTransparency() != 1f)
+    {
+      g = goff;
+      if (defaultColour != 0)
+      {
+        offscreenImage.setRGB(0, 0, defaultColour);
+      }
+    }
+
+    Color c = featureRenderer.findFeatureColour(seq, column + 1, g);
+    if (c == null)
+    {
+      return defaultColour;
+    }
+
+    if (g != null)
+    {
+      return offscreenImage.getRGB(0, 0);
+    }
+    return c.getRGB();
+  }
+  /**
+   * Answers true if feature display is turned off, or there are no features
+   * configured to be visible
+   * 
+   * @return
+   */
+  public boolean noFeaturesDisplayed()
+  {
+    if (featureRenderer == null
+            || !featureRenderer.getViewport().isShowSequenceFeatures())
+    {
+      return true;
+    }
+
+    if (!((FeatureRendererModel) featureRenderer).hasRenderOrder())
+    {
+      return true;
+    }
+
+    FeaturesDisplayedI displayed = featureRenderer.getFeaturesDisplayed();
+    if (displayed == null || displayed.getVisibleFeatureCount() == 0)
+    {
+      return true;
+    }
+
+    return false;
+  }
 }