JAL-2438 unit test, fixes, Javadoc updates
[jalview.git] / src / jalview / renderer / seqfeatures / FeatureColourFinder.java
1 package jalview.renderer.seqfeatures;
2
3 import jalview.api.FeaturesDisplayedI;
4 import jalview.datamodel.SequenceI;
5 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
6
7 import java.awt.Color;
8 import java.awt.Graphics;
9 import java.awt.image.BufferedImage;
10
11 /**
12  * A helper class to find feature colour using an associated FeatureRenderer
13  * 
14  * @author gmcarstairs
15  *
16  */
17 public class FeatureColourFinder
18 {
19   /*
20    * the class we delegate feature finding to
21    */
22   private jalview.api.FeatureRenderer featureRenderer;
23
24   /*
25    * a 1-pixel image on which features can be drawn, for the case where
26    * transparency allows 'see-through' of multiple feature colours
27    */
28   private BufferedImage offscreenImage;
29
30   /**
31    * Constructor
32    * 
33    * @param fr
34    */
35   public FeatureColourFinder(jalview.api.FeatureRenderer fr)
36   {
37     featureRenderer = fr;
38     offscreenImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
39   }
40
41   /**
42    * Answers the feature colour to show for the given sequence and column
43    * position. This delegates to the FeatureRenderer to find the colour, which
44    * will depend on feature location, visibility, ordering, colour scheme, and
45    * whether or not transparency is applied. For feature rendering with
46    * transparency, this class provides a dummy 'offscreen' graphics context
47    * where multiple feature colours can be overlaid and the combined colour read
48    * back.
49    * 
50    * @param defaultColour
51    * @param seq
52    * @param column
53    *          alignment column position (base zero)
54    * @return
55    */
56   public Color findFeatureColour(Color defaultColour, SequenceI seq,
57           int column)
58   {
59     if (!((FeatureRendererModel) featureRenderer).hasRenderOrder())
60     {
61       return defaultColour;
62     }
63
64     FeaturesDisplayedI displayed = featureRenderer.getFeaturesDisplayed();
65     if (displayed == null || displayed.getVisibleFeatureCount() == 0)
66     {
67       return defaultColour; // nothing to see here folks
68     }
69
70     Graphics g = null;
71
72     /*
73      * if transparency applies, get colours drawn to a 1x1 pixel
74      * graphics context that has been primed with the default colour
75      */
76     if (featureRenderer.getTransparency() != 1f)
77     {
78       g = offscreenImage.getGraphics();
79       offscreenImage.setRGB(0, 0, defaultColour.getRGB());
80     }
81
82     Color c = featureRenderer.findFeatureColour(seq, column, g);
83
84     if (c != null && g != null)
85     {
86       c = new Color(offscreenImage.getRGB(0, 0));
87     }
88     return c == null ? defaultColour : c;
89   }
90 }