import jalview.api.AlignViewportI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.renderer.ResidueShaderI;
+import jalview.renderer.ResidueColourFinder;
import jalview.renderer.seqfeatures.FeatureColourFinder;
-import jalview.util.Comparison;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import org.jfree.graphics2d.svg.SVGGraphics2D;
+import org.jibble.epsgraphics.EpsGraphics2D;
+
public class SequenceRenderer implements jalview.api.SequenceRenderer
{
final static int CHAR_TO_UPPER = 'A' - 'a';
boolean renderGaps = true;
- SequenceGroup currentSequenceGroup = null;
-
SequenceGroup[] allGroups = null;
- Color resBoxColour;
+ // Color resBoxColour;
Graphics graphics;
boolean monospacedFont;
- boolean forOverview = false;
+ ResidueColourFinder resColourFinder;
/**
* Creates a new SequenceRenderer object
public SequenceRenderer(AlignViewportI viewport)
{
this.av = viewport;
+ resColourFinder = new ResidueColourFinder();
}
/**
// If EPS graphics, stringWidth will be a double, not an int
double dwidth = fm.getStringBounds("M", g).getWidth();
- monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth() && av
- .getCharWidth() == dwidth);
+ monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth()
+ && av.getCharWidth() == dwidth);
this.renderGaps = renderGaps;
}
- protected Color getResidueBoxColour(SequenceI seq, int i)
- {
- // rate limiting step when rendering overview for lots of groups
- allGroups = av.getAlignment().findAllGroups(seq);
-
- if (inCurrentSequenceGroup(i))
- {
- if (currentSequenceGroup.getDisplayBoxes())
- {
- getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i);
- }
- }
- else if (av.getShowBoxes())
- {
- getBoxColour(av.getResidueShading(), seq, i);
- }
-
- return resBoxColour;
- }
-
/**
* Get the residue colour at the given sequence position - as determined by
* the sequence group colour (if any), else the colour scheme, possibly
public Color getResidueColour(final SequenceI seq, int position,
FeatureColourFinder finder)
{
- Color col = getResidueBoxColour(seq, position);
-
- if (finder != null)
- {
- col = finder.findFeatureColour(col, seq, position);
- }
- return col;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param shader
- * DOCUMENT ME!
- * @param seq
- * DOCUMENT ME!
- * @param i
- * DOCUMENT ME!
- */
- void getBoxColour(ResidueShaderI shader, SequenceI seq, int i)
- {
- if (shader.getColourScheme() != null)
- {
- if (forOverview && Comparison.isGap(seq.getCharAt(i))
- && !shader.getColourScheme().hasGapColour())
- {
- resBoxColour = Color.lightGray;
- }
- else
- {
- resBoxColour = shader.findColour(seq.getCharAt(i),
- i, seq);
- }
- }
- else if (forOverview && Comparison.isGap(seq.getCharAt(i)))
- {
- resBoxColour = Color.lightGray;
- }
- else
- {
- resBoxColour = Color.white;
- }
+ allGroups = av.getAlignment().findAllGroups(seq);
+ return resColourFinder.getResidueColour(av.getShowBoxes(),
+ av.getResidueShading(),
+ allGroups, seq, position,
+ finder);
}
/**
public synchronized void drawBoxes(SequenceI seq, int start, int end,
int y1)
{
+ Color resBoxColour = Color.white;
+
if (seq == null)
{
return; // fix for racecondition
int length = seq.getLength();
int curStart = -1;
- int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(), avHeight = av
- .getCharHeight();
+ int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(),
+ avHeight = av.getCharHeight();
Color tempColour = null;
if (i < length)
{
- if (inCurrentSequenceGroup(i))
+ SequenceGroup currentSequenceGroup = resColourFinder
+ .getCurrentSequenceGroup(
+ allGroups, i);
+ if (currentSequenceGroup != null)
{
if (currentSequenceGroup.getDisplayBoxes())
{
- getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq,
+ resBoxColour = resColourFinder.getBoxColour(
+ currentSequenceGroup.getGroupColourScheme(), seq,
i);
}
}
else if (av.getShowBoxes())
{
- getBoxColour(av.getResidueShading(), seq, i);
+ resBoxColour = resColourFinder
+ .getBoxColour(av.getResidueShading(), seq, i);
}
}
}
graphics.setColor(av.getTextColour());
- if (monospacedFont && av.getShowText() && allGroups.length == 0
- && !av.getColourText() && av.getThresholdTextColour() == 0)
+ boolean drawAllText = monospacedFont && av.getShowText() && allGroups.length == 0
+ && !av.getColourText() && av.getThresholdTextColour() == 0;
+
+ /*
+ * EPS or SVG misaligns monospaced strings (JAL-3239)
+ * so always draw these one character at a time
+ */
+ if (graphics instanceof EpsGraphics2D
+ || graphics instanceof SVGGraphics2D)
+ {
+ drawAllText = false;
+ }
+ if (drawAllText)
{
if (av.isRenderGaps())
{
else
{
char gap = av.getGapCharacter();
- graphics.drawString(seq.getSequenceAsString(start, end + 1)
- .replace(gap, ' '), 0, y1);
+ graphics.drawString(
+ seq.getSequenceAsString(start, end + 1).replace(gap, ' '),
+ 0, y1);
}
}
else
boolean srep = av.isDisplayReferenceSeq();
boolean getboxColour = false;
boolean isarep = av.getAlignment().getSeqrep() == seq;
- boolean isgrep = currentSequenceGroup != null ? currentSequenceGroup
- .getSeqrep() == seq : false;
- char sr_c;
+ Color resBoxColour = Color.white;
+
for (int i = start; i <= end; i++)
{
continue;
}
- if (inCurrentSequenceGroup(i))
+ SequenceGroup currentSequenceGroup = resColourFinder
+ .getCurrentSequenceGroup(
+ allGroups, i);
+ if (currentSequenceGroup != null)
{
if (!currentSequenceGroup.getDisplayText())
{
|| currentSequenceGroup.getColourText())
{
getboxColour = true;
- getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq,
+ resBoxColour = resColourFinder.getBoxColour(
+ currentSequenceGroup.getGroupColourScheme(), seq,
i);
if (currentSequenceGroup.getColourText())
if (currentSequenceGroup.thresholdTextColour > 0)
{
if (resBoxColour.getRed() + resBoxColour.getBlue()
- + resBoxColour.getGreen() < currentSequenceGroup.thresholdTextColour)
+ + resBoxColour
+ .getGreen() < currentSequenceGroup.thresholdTextColour)
{
graphics.setColor(currentSequenceGroup.textColour2);
}
{
graphics.setColor(currentSequenceGroup.textColour);
}
+ boolean isgrep = currentSequenceGroup != null
+ ? currentSequenceGroup.getSeqrep() == seq : false;
if (!isarep && !isgrep
&& currentSequenceGroup.getShowNonconserved()) // todo
// optimize
if (av.getColourText())
{
getboxColour = true;
- getBoxColour(av.getResidueShading(), seq, i);
+ resBoxColour = resColourFinder
+ .getBoxColour(av.getResidueShading(), seq, i);
if (av.getShowBoxes())
{
{
if (!getboxColour)
{
- getBoxColour(av.getResidueShading(), seq, i);
+ resBoxColour = resColourFinder
+ .getBoxColour(av.getResidueShading(), seq, i);
}
if (resBoxColour.getRed() + resBoxColour.getBlue()
// currentSequenceGroup.getConsensus()
char conschar = (usesrep) ? (currentGroup == null
|| position < currentGroup.getStartRes()
- || position > currentGroup.getEndRes() ? av.getAlignment()
- .getSeqrep().getCharAt(position)
- : (currentGroup.getSeqrep() != null ? currentGroup.getSeqrep()
- .getCharAt(position) : av.getAlignment().getSeqrep()
- .getCharAt(position)))
+ || position > currentGroup.getEndRes()
+ ? av.getAlignment().getSeqrep().getCharAt(position)
+ : (currentGroup.getSeqrep() != null
+ ? currentGroup.getSeqrep().getCharAt(position)
+ : av.getAlignment().getSeqrep()
+ .getCharAt(position)))
: (currentGroup != null && currentGroup.getConsensus() != null
&& position >= currentGroup.getStartRes()
- && position <= currentGroup.getEndRes() && currentGroup
- .getConsensus().annotations.length > position) ? currentGroup
- .getConsensus().annotations[position].displayCharacter
- .charAt(0)
- : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
- .charAt(0);
+ && position <= currentGroup.getEndRes()
+ && currentGroup
+ .getConsensus().annotations.length > position)
+ ? currentGroup
+ .getConsensus().annotations[position].displayCharacter
+ .charAt(0)
+ : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
+ .charAt(0);
if (!jalview.util.Comparison.isGap(conschar)
- && (sequenceChar == conschar || sequenceChar + CHAR_TO_UPPER == conschar))
+ && (sequenceChar == conschar
+ || sequenceChar + CHAR_TO_UPPER == conschar))
{
sequenceChar = conservedChar;
}
/**
* DOCUMENT ME!
*
- * @param res
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- boolean inCurrentSequenceGroup(int res)
- {
- if (allGroups == null)
- {
- return false;
- }
-
- for (int i = 0; i < allGroups.length; i++)
- {
- if ((allGroups[i].getStartRes() <= res)
- && (allGroups[i].getEndRes() >= res))
- {
- currentSequenceGroup = allGroups[i];
-
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * DOCUMENT ME!
- *
* @param seq
* DOCUMENT ME!
* @param start
* @param height
* DOCUMENT ME!
*/
- public void drawHighlightedText(SequenceI seq, int start, int end,
- int x1, int y1)
+ public void drawHighlightedText(SequenceI seq, int start, int end, int x1,
+ int y1)
{
int pady = av.getCharHeight() / 5;
int charOffset = 0;
}
}
- public void drawCursor(SequenceI seq, int res, int x1, int y1)
+ /**
+ * Draw a sequence canvas cursor
+ *
+ * @param g
+ * graphics context to draw on
+ * @param s
+ * character to draw at cursor
+ * @param x1
+ * x position of cursor in graphics context
+ * @param y1
+ * y position of cursor in graphics context
+ */
+ public void drawCursor(Graphics g, char s, int x1, int y1)
{
int pady = av.getCharHeight() / 5;
int charOffset = 0;
- graphics.setColor(Color.black);
- graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
+ g.setColor(Color.black);
+ g.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
if (av.isValidCharWidth())
{
- graphics.setColor(Color.white);
-
- char s = seq.getCharAt(res);
-
+ g.setColor(Color.white);
charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
- graphics.drawString(String.valueOf(s), charOffset + x1,
+ g.drawString(String.valueOf(s), charOffset + x1,
(y1 + av.getCharHeight()) - pady);
}