overlaps = seq.getFeatures().findFeatures(
visiblePositions.getBegin(), visiblePositions.getEnd(), type);
if (fc.isSimpleColour())
{
filterFeaturesForDisplay(overlaps);
}
for (SequenceFeature sf : overlaps)
{
Color featureColour = getColor(sf, fc);
if (featureColour == null)
{
/*
* feature excluded by visibility settings, filters, or colour threshold
*/
continue;
}
/*
* if feature starts/ends outside the visible range,
* restrict to visible positions (or if a contact feature,
* to a single position)
*/
int visibleStart = sf.getBegin();
if (visibleStart < visiblePositions.getBegin())
{
visibleStart = sf.isContactFeature() ? sf.getEnd()
: visiblePositions.getBegin();
}
int visibleEnd = sf.getEnd();
if (visibleEnd > visiblePositions.getEnd())
{
visibleEnd = sf.isContactFeature() ? sf.getBegin()
: visiblePositions.getEnd();
}
int featureStartCol = seq.findIndex(visibleStart);
int featureEndCol = sf.begin == sf.end ? featureStartCol : seq
.findIndex(visibleEnd);
// Color featureColour = getColour(sequenceFeature);
boolean isContactFeature = sf.isContactFeature();
if (isContactFeature)
{
boolean drawn = renderFeature(g, seq, featureStartCol - 1,
featureStartCol - 1, featureColour, start, end, y1,
colourOnly);
drawn |= renderFeature(g, seq, featureEndCol - 1,
featureEndCol - 1, featureColour, start, end, y1,
colourOnly);
if (drawn)
{
drawnColour = featureColour;
}
}
else
{
/*
* showing feature score by height of colour
* is not implemented as a selectable option
*
if (av.isShowSequenceFeaturesHeight()
&& !Float.isNaN(sequenceFeature.score))
{
boolean drawn = renderScoreFeature(g, seq,
seq.findIndex(sequenceFeature.begin) - 1,
seq.findIndex(sequenceFeature.end) - 1, featureColour,
start, end, y1, normaliseScore(sequenceFeature),
colourOnly);
if (drawn)
{
drawnColour = featureColour;
}
}
else
{
*/
boolean drawn = renderFeature(g, seq,
featureStartCol - 1,
featureEndCol - 1, featureColour,
start, end, y1, colourOnly);
if (drawn)
{
drawnColour = featureColour;
}
/*}*/
}
}
}
if (transparency != 1.0f && g != null)
{
/*
* reset transparency
*/
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(NO_TRANSPARENCY);
}
return drawnColour;
}
/**
* Called when alignment in associated view has new/modified features to
* discover and display.
*
*/
@Override
public void featuresAdded()
{
findAllFeatures();
}
/**
* Returns the sequence feature colour rendered at the given column 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. This method is suitable when no feature transparency
* applied (only the topmost visible feature colour is rendered).
*
* Note this method does not check for a gap in the column so would return the
* colour for features enclosing a gapped column. Check for gap before calling
* if different behaviour is wanted.
*
* @param seq
* @param column
* (1..)
* @return
*/
Color findFeatureColour(SequenceI seq, int column)
{
/*
* 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;
}
List overlaps = seq.findFeatures(column, column,
type);
for (SequenceFeature sequenceFeature : overlaps)
{
if (!featureGroupNotShown(sequenceFeature))
{
Color col = getColour(sequenceFeature);
if (col != null)
{
return col;
}
}
}
}
/*
* no displayed feature found at position
*/
return null;
}
}