+
+ /**
+ * Returns the sequence feature colour rendered at the given sequence
+ * position, or null if none found. The feature of highest render order (i.e.
+ * on top) is found, subject to both feature type and feature group being
+ * visible, and its colour returned.
+ *
+ * @param seq
+ * @param pos
+ * @return
+ */
+ Color findFeatureColour(SequenceI seq, int pos)
+ {
+ SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
+ if (sequenceFeatures == null || sequenceFeatures.length == 0)
+ {
+ return null;
+ }
+
+ /*
+ * check for new feature added while processing
+ */
+ updateFeatures();
+
+ /*
+ * inspect features in reverse renderOrder (the last in the array is
+ * displayed on top) until we find one that is rendered at the position
+ */
+ for (int renderIndex = renderOrder.length - 1; renderIndex >= 0; renderIndex--)
+ {
+ String type = renderOrder[renderIndex];
+ if (!showFeatureOfType(type))
+ {
+ continue;
+ }
+
+ for (int sfindex = 0; sfindex < sequenceFeatures.length; sfindex++)
+ {
+ SequenceFeature sequenceFeature = sequenceFeatures[sfindex];
+ if (!sequenceFeature.type.equals(type))
+ {
+ continue;
+ }
+
+ if (featureGroupNotShown(sequenceFeature))
+ {
+ 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())
+ {
+ featureIsAtPosition = sequenceFeature.begin == pos
+ || sequenceFeature.end == pos;
+ }
+ if (featureIsAtPosition)
+ {
+ return getColour(sequenceFeature);
+ }
+ }
+ }
+
+ /*
+ * no displayed feature found at position
+ */
+ return null;
+ }