X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Frenderer%2Fseqfeatures%2FFeatureRenderer.java;h=759101d606625bb52322142903f58f641af63d17;hb=refs%2Fheads%2Fbug%2FJAL-2630gradColourUpdateOverview;hp=de3b201e83e13bb14b0c7e06527780dc6ab33f5a;hpb=2888e7307e1f7c8239234941498cb86e8c65ab36;p=jalview.git diff --git a/src/jalview/renderer/seqfeatures/FeatureRenderer.java b/src/jalview/renderer/seqfeatures/FeatureRenderer.java index de3b201..759101d 100644 --- a/src/jalview/renderer/seqfeatures/FeatureRenderer.java +++ b/src/jalview/renderer/seqfeatures/FeatureRenderer.java @@ -31,21 +31,12 @@ import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.image.BufferedImage; public class FeatureRenderer extends FeatureRendererModel { private static final AlphaComposite NO_TRANSPARENCY = AlphaComposite .getInstance(AlphaComposite.SRC_OVER, 1.0f); - protected SequenceI lastSeq; - - BufferedImage offscreenImage; - - private volatile SequenceFeature[] lastSequenceFeatures; - - int sfSize; - /** * Constructor given a viewport * @@ -213,78 +204,64 @@ public class FeatureRenderer extends FeatureRendererModel } /** - * This is used by Structure Viewers and the Overview Window to get the - * feature colour of the rendered sequence - * - * @param defaultColour - * @param seq - * @param column - * @return + * {@inheritDoc} */ @Override - public Color findFeatureColour(Color defaultColour, SequenceI seq, - int column, Graphics g) + public Color findFeatureColour(SequenceI seq, int column, Graphics g) { if (!av.isShowSequenceFeatures()) { - return defaultColour; + return null; } SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures(); - if (seq != lastSeq) - { - lastSeq = seq; - lastSequenceFeatures = sequenceFeatures; - if (lastSequenceFeatures != null) - { - sfSize = lastSequenceFeatures.length; - } - } - else - { - if (lastSequenceFeatures != sequenceFeatures) - { - lastSequenceFeatures = sequenceFeatures; - if (lastSequenceFeatures != null) - { - sfSize = lastSequenceFeatures.length; - } - } - } - if (lastSequenceFeatures == null || sfSize == 0) + if (sequenceFeatures == null || sequenceFeatures.length == 0) { - return defaultColour; + return null; } - if (Comparison.isGap(lastSeq.getCharAt(column))) + if (Comparison.isGap(seq.getCharAt(column))) { - return Color.white; + /* + * returning null allows the colour scheme to provide gap colour + * - normally white, but can be customised otherwise + */ + return null; } Color renderedColour = null; if (transparency == 1.0f) { + /* + * simple case - just find the topmost rendered visible feature colour + */ renderedColour = findFeatureColour(seq, seq.findPosition(column)); } else { - renderedColour = drawSequence(g, lastSeq, column, column, 0, true); + /* + * transparency case - draw all visible features in render order to + * build up a composite colour on the graphics context + */ + renderedColour = drawSequence(g, seq, column, column, 0, true); } - return renderedColour == null ? defaultColour : renderedColour; + return renderedColour; } /** * Draws the sequence features on the graphics context, or just determines the - * colour that would be drawn (if flag offscreenrender is true). + * colour that would be drawn (if flag colourOnly is true). Returns the last + * colour drawn (which may not be the effective colour if transparency + * applies), or null if no feature is drawn in the range given. * * @param g * the graphics context to draw on (may be null if colourOnly==true) * @param seq * @param start - * start column (or sequence position in offscreenrender mode) + * start column * @param end - * end column (not used in offscreenrender mode) + * end column * @param y1 * vertical offset at which to draw on the graphics * @param colourOnly @@ -304,13 +281,6 @@ public class FeatureRenderer extends FeatureRendererModel updateFeatures(); - if (lastSeq == null || seq != lastSeq - || sequenceFeatures != lastSequenceFeatures) - { - lastSeq = seq; - lastSequenceFeatures = sequenceFeatures; - } - if (transparency != 1f && g != null) { Graphics2D g2 = (Graphics2D) g; @@ -318,17 +288,14 @@ public class FeatureRenderer extends FeatureRendererModel transparency)); } - int startPos = lastSeq.findPosition(start); - int endPos = lastSeq.findPosition(end); + int startPos = seq.findPosition(start); + int endPos = seq.findPosition(end); - sfSize = lastSequenceFeatures.length; + int sfSize = sequenceFeatures.length; Color drawnColour = null; /* - * iterate over features in ordering of their rendering; - * if drawing a range of columns, use render order to ensure last is on top - * if drawing a single column (as in findFeatureColour), with no - * transparency, work backwards to find the topmost rendered feature colour + * iterate over features in ordering of their rendering (last is on top) */ for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++) { @@ -342,21 +309,24 @@ public class FeatureRenderer extends FeatureRendererModel // current feature to render for (int sfindex = 0; sfindex < sfSize; sfindex++) { - final SequenceFeature sequenceFeature = lastSequenceFeatures[sfindex]; + final SequenceFeature sequenceFeature = sequenceFeatures[sfindex]; if (!sequenceFeature.type.equals(type)) { continue; } + /* + * a feature type may be flagged as shown but the group + * an instance of it belongs to may be hidden + */ if (featureGroupNotShown(sequenceFeature)) { continue; } /* - * check feature overlaps the visible part of the alignment, - * unless doing offscreenRender (to the Overview window or a - * structure viewer) which is not limited + * check feature overlaps the target range + * TODO: efficient retrieval of features overlapping a range */ if (sequenceFeature.getBegin() > endPos || sequenceFeature.getEnd() < startPos) @@ -365,6 +335,12 @@ public class FeatureRenderer extends FeatureRendererModel } Color featureColour = getColour(sequenceFeature); + if (featureColour == null) + { + // score feature outwith threshold for colouring + continue; + } + boolean isContactFeature = sequenceFeature.isContactFeature(); if (isContactFeature) @@ -382,7 +358,7 @@ public class FeatureRenderer extends FeatureRendererModel drawnColour = featureColour; } } - else if (showFeature(sequenceFeature)) + else { if (av.isShowSequenceFeaturesHeight() && !Float.isNaN(sequenceFeature.score)) @@ -415,13 +391,8 @@ public class FeatureRenderer extends FeatureRendererModel if (transparency != 1.0f && g != null) { /* - * get colour as rendered including transparency - * and reset transparency + * reset transparency */ - if (offscreenImage != null && drawnColour != null) - { - drawnColour = new Color(offscreenImage.getRGB(0, 0)); - } Graphics2D g2 = (Graphics2D) g; g2.setComposite(NO_TRANSPARENCY); } @@ -455,7 +426,6 @@ public class FeatureRenderer extends FeatureRendererModel @Override public void featuresAdded() { - lastSeq = null; findAllFeatures(); } @@ -477,7 +447,10 @@ public class FeatureRenderer extends FeatureRendererModel return null; } - // updateFeatures(); + /* + * check for new feature added while processing + */ + updateFeatures(); /* * inspect features in reverse renderOrder (the last in the array is @@ -504,6 +477,10 @@ public class FeatureRenderer extends FeatureRendererModel continue; } + /* + * check the column position is within the feature range + * (or is one of the two contact positions for a contact feature) + */ boolean featureIsAtPosition = sequenceFeature.begin <= pos && sequenceFeature.end >= pos; if (sequenceFeature.isContactFeature())