- if (showFeature(sequenceFeatures[sfindex]))
- {
- if (av.showSeqFeaturesHeight
- && sequenceFeatures[sfindex].score != Float.NaN)
- {
- renderScoreFeature(g, seq, seq
- .findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex]), start, end,
- y1, normaliseScore(sequenceFeatures[sfindex]));
- }
- else
- {
- renderFeature(g, seq, seq
- .findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex]), start, end,
- y1);
- }
- }
-
- }
-
- }
-
- if (transparency != 1.0f && g != null)
- {
- Graphics2D g2 = (Graphics2D) g;
- g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- 1.0f));
- }
- }
-
- Hashtable minmax = new Hashtable();
-
- /**
- * normalise a score against the max/min bounds for the feature type.
- *
- * @param sequenceFeature
- * @return byte[] { signed, normalised signed (-127 to 127) or unsigned
- * (0-255) value.
- */
- private final byte[] normaliseScore(SequenceFeature sequenceFeature)
- {
- float[] mm = ((float[][]) minmax.get(sequenceFeature.type))[0];
- final byte[] r = new byte[]
- { 0, (byte) 255 };
- if (mm != null)
- {
- if (r[0] != 0 || mm[0] < 0.0)
- {
- r[0] = 1;
- r[1] = (byte) ((int) 128.0 + 127.0 * (sequenceFeature.score / mm[1]));
- }
- else
- {
- r[1] = (byte) ((int) 255.0 * (sequenceFeature.score / mm[1]));
- }
- }
- return r;
- }
-
- char s;
-
- int i;
-
- void renderFeature(Graphics g, SequenceI seq, int fstart, int fend,
- Color featureColour, int start, int end, int y1)
- {
-
- if (((fstart <= end) && (fend >= start)))
- {
- if (fstart < start)
- { // fix for if the feature we have starts before the sequence start,
- fstart = start; // but the feature end is still valid!!
- }
-
- if (fend >= end)
- {
- fend = end;
- }
- int pady = (y1 + av.charHeight) - av.charHeight / 5;
- for (i = fstart; i <= fend; i++)
- {
- s = seq.getCharAt(i);
-
- if (jalview.util.Comparison.isGap(s))
- {
- continue;
- }
-
- g.setColor(featureColour);
-
- g.fillRect((i - start) * av.charWidth, y1, av.charWidth,
- av.charHeight);
-
- if (offscreenRender || !av.validCharWidth)
- {
- continue;
- }
-
- g.setColor(Color.white);
- charOffset = (av.charWidth - fm.charWidth(s)) / 2;
- g.drawString(String.valueOf(s), charOffset
- + (av.charWidth * (i - start)), pady);
-
- }
- }
- }
-
- void renderScoreFeature(Graphics g, SequenceI seq, int fstart, int fend,
- Color featureColour, int start, int end, int y1, byte[] bs)
- {
-
- if (((fstart <= end) && (fend >= start)))
- {
- if (fstart < start)
- { // fix for if the feature we have starts before the sequence start,
- fstart = start; // but the feature end is still valid!!
- }
-
- if (fend >= end)
- {
- fend = end;
- }
- int pady = (y1 + av.charHeight) - av.charHeight / 5;
- int ystrt = 0, yend = av.charHeight;
- if (bs[0] != 0)
- {
- // signed - zero is always middle of residue line.
- if (bs[1] < 128)
- {
- yend = av.charHeight * (128 - bs[1]) / 512;
- ystrt = av.charHeight - yend / 2;
- }
- else
- {
- ystrt = av.charHeight / 2;
- yend = av.charHeight * (bs[1] - 128) / 512;
- }
- }
- else
- {
- yend = av.charHeight * bs[1] / 255;
- ystrt = av.charHeight - yend;
-
- }
- for (i = fstart; i <= fend; i++)
- {
- s = seq.getCharAt(i);
-
- if (jalview.util.Comparison.isGap(s))
- {
- continue;
- }
-
- g.setColor(featureColour);
- int x = (i - start) * av.charWidth;
- g.drawRect(x, y1, av.charWidth, av.charHeight);
- g.fillRect(x, y1 + ystrt, av.charWidth, yend);
-
- if (offscreenRender || !av.validCharWidth)
- {
- continue;
- }
-
- g.setColor(Color.black);
- charOffset = (av.charWidth - fm.charWidth(s)) / 2;
- g.drawString(String.valueOf(s), charOffset
- + (av.charWidth * (i - start)), pady);
-
- }
- }
- }
-
- boolean newFeatureAdded = false;
-
- /**
- * Called when alignment in associated view has new/modified features to
- * discover and display.
- *
- */
- public void featuresAdded()
- {
- lastSeq = null;
- findAllFeatures();
- }
-
- boolean findingFeatures = false;
-
- /**
- * search the alignment for all new features, give them a colour and display
- * them. Then fires a PropertyChangeEvent on the changeSupport object.
- *
- */
- void findAllFeatures()
- {
- synchronized (firing)
- {
- if (firing.equals(Boolean.FALSE))
- {
- firing = Boolean.TRUE;
- findAllFeatures(true); // add all new features as visible
- changeSupport.firePropertyChange("changeSupport", null, null);
- firing = Boolean.FALSE;
- }
- }
- }
-
- /**
- * Searches alignment for all features and updates colours
- *
- * @param newMadeVisible
- * if true newly added feature types will be rendered
- * immediatly
- */
- synchronized void findAllFeatures(boolean newMadeVisible)
- {
- newFeatureAdded = false;
-
- if (findingFeatures)
- {
- newFeatureAdded = true;
- return;
- }
-
- findingFeatures = true;
-
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable();
- }
-
- allfeatures = new Vector();
- Vector oldfeatures = new Vector();
- if (renderOrder != null)
- {
- for (int i = 0; i < renderOrder.length; i++)
- {
- if (renderOrder[i] != null)
- {
- oldfeatures.addElement(renderOrder[i]);
- }
- }
- }
- if (minmax == null)
- {
- minmax = new Hashtable();
- }
- for (int i = 0; i < av.alignment.getHeight(); i++)
- {
- SequenceFeature[] features = av.alignment.getSequenceAt(i)
- .getDatasetSequence().getSequenceFeatures();
-
- if (features == null)
- {
- continue;
- }
-
- int index = 0;
- while (index < features.length)
- {
- if (!av.featuresDisplayed.containsKey(features[index].getType()))