Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.gui

File SequenceRenderer.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
35% of files have more coverage

Code metrics

76
118
9
1
512
305
64
0.54
13.11
9
7.11

Classes

Class Line # Actions
SequenceRenderer 33 118 64 82
0.596059159.6%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import jalview.api.AlignViewportI;
24    import jalview.datamodel.SequenceGroup;
25    import jalview.datamodel.SequenceI;
26    import jalview.renderer.ResidueColourFinder;
27    import jalview.renderer.seqfeatures.FeatureColourFinder;
28   
29    import java.awt.Color;
30    import java.awt.FontMetrics;
31    import java.awt.Graphics;
32   
 
33    public class SequenceRenderer implements jalview.api.SequenceRenderer
34    {
35    final static int CHAR_TO_UPPER = 'A' - 'a';
36   
37    AlignViewportI av;
38   
39    FontMetrics fm;
40   
41    boolean renderGaps = true;
42   
43    SequenceGroup[] allGroups = null;
44   
45    // Color resBoxColour;
46   
47    Graphics graphics;
48   
49    boolean monospacedFont;
50   
51    ResidueColourFinder resColourFinder;
52   
53    /**
54    * Creates a new SequenceRenderer object
55    *
56    * @param viewport
57    */
 
58  231 toggle public SequenceRenderer(AlignViewportI viewport)
59    {
60  231 this.av = viewport;
61  231 resColourFinder = new ResidueColourFinder();
62    }
63   
64    /**
65    * DOCUMENT ME!
66    *
67    * @param b
68    * DOCUMENT ME!
69    */
 
70  1028 toggle public void prepare(Graphics g, boolean renderGaps)
71    {
72  1028 graphics = g;
73  1028 fm = g.getFontMetrics();
74   
75    // If EPS graphics, stringWidth will be a double, not an int
76  1028 double dwidth = fm.getStringBounds("M", g).getWidth();
77   
78  1028 monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth()
79    && av.getCharWidth() == dwidth);
80   
81  1028 this.renderGaps = renderGaps;
82    }
83   
84    /**
85    * Get the residue colour at the given sequence position - as determined by
86    * the sequence group colour (if any), else the colour scheme, possibly
87    * overridden by a feature colour.
88    *
89    * @param seq
90    * @param position
91    * @param finder
92    * @return
93    */
 
94  3315 toggle @Override
95    public Color getResidueColour(final SequenceI seq, int position,
96    FeatureColourFinder finder)
97    {
98  3315 allGroups = av.getAlignment().findAllGroups(seq);
99  3315 return resColourFinder.getResidueColour(av.getShowBoxes(),
100    av.getResidueShading(),
101    allGroups, seq, position,
102    finder);
103    }
104   
105    /**
106    * DOCUMENT ME!
107    *
108    * @param g
109    * DOCUMENT ME!
110    * @param seq
111    * DOCUMENT ME!
112    * @param sg
113    * DOCUMENT ME!
114    * @param start
115    * DOCUMENT ME!
116    * @param end
117    * DOCUMENT ME!
118    * @param x1
119    * DOCUMENT ME!
120    * @param y1
121    * DOCUMENT ME!
122    * @param width
123    * DOCUMENT ME!
124    * @param height
125    * DOCUMENT ME!
126    */
 
127  6193 toggle public void drawSequence(SequenceI seq, SequenceGroup[] sg, int start,
128    int end, int y1)
129    {
130  6193 allGroups = sg;
131   
132  6193 drawBoxes(seq, start, end, y1);
133   
134  6193 if (av.isValidCharWidth())
135    {
136  6193 drawText(seq, start, end, y1);
137    }
138    }
139   
140    /**
141    * DOCUMENT ME!
142    *
143    * @param seq
144    * DOCUMENT ME!
145    * @param start
146    * DOCUMENT ME!
147    * @param end
148    * DOCUMENT ME!
149    * @param x1
150    * DOCUMENT ME!
151    * @param y1
152    * DOCUMENT ME!
153    * @param width
154    * DOCUMENT ME!
155    * @param height
156    * DOCUMENT ME!
157    */
 
158  6193 toggle public synchronized void drawBoxes(SequenceI seq, int start, int end,
159    int y1)
160    {
161  6193 Color resBoxColour = Color.white;
162   
163  6193 if (seq == null)
164    {
165  0 return; // fix for racecondition
166    }
167  6193 int i = start;
168  6193 int length = seq.getLength();
169   
170  6193 int curStart = -1;
171  6193 int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(),
172    avHeight = av.getCharHeight();
173   
174  6193 Color tempColour = null;
175   
176  354705 while (i <= end)
177    {
178  348512 resBoxColour = Color.white;
179   
180  348512 if (i < length)
181    {
182  348330 SequenceGroup currentSequenceGroup = resColourFinder
183    .getCurrentSequenceGroup(
184    allGroups, i);
185  348330 if (currentSequenceGroup != null)
186    {
187  264784 if (currentSequenceGroup.getDisplayBoxes())
188    {
189  264784 resBoxColour = resColourFinder.getBoxColour(
190    currentSequenceGroup.getGroupColourScheme(), seq,
191    i);
192    }
193    }
194  83546 else if (av.getShowBoxes())
195    {
196  83546 resBoxColour = resColourFinder
197    .getBoxColour(av.getResidueShading(), seq, i);
198    }
199    }
200   
201  348512 if (resBoxColour != tempColour)
202    {
203  228234 if (tempColour != null)
204    {
205  222042 graphics.fillRect(avWidth * (curStart - start), y1, curWidth,
206    avHeight);
207    }
208   
209  228234 graphics.setColor(resBoxColour);
210   
211  228234 curStart = i;
212  228234 curWidth = avWidth;
213  228234 tempColour = resBoxColour;
214    }
215    else
216    {
217  120278 curWidth += avWidth;
218    }
219   
220  348512 i++;
221    }
222   
223  6193 graphics.fillRect(avWidth * (curStart - start), y1, curWidth, avHeight);
224   
225    }
226   
227    /**
228    * DOCUMENT ME!
229    *
230    * @param seq
231    * DOCUMENT ME!
232    * @param start
233    * DOCUMENT ME!
234    * @param end
235    * DOCUMENT ME!
236    * @param x1
237    * DOCUMENT ME!
238    * @param y1
239    * DOCUMENT ME!
240    * @param width
241    * DOCUMENT ME!
242    * @param height
243    * DOCUMENT ME!
244    */
 
245  6193 toggle public void drawText(SequenceI seq, int start, int end, int y1)
246    {
247  6193 y1 += av.getCharHeight() - av.getCharHeight() / 5; // height/5 replaces pady
248  6193 int charOffset = 0;
249  6193 char s;
250   
251  6193 if (end + 1 >= seq.getLength())
252    {
253  39 end = seq.getLength() - 1;
254    }
255  6193 graphics.setColor(av.getTextColour());
256   
257  6193 if (monospacedFont && av.getShowText() && allGroups.length == 0
258    && !av.getColourText() && av.getThresholdTextColour() == 0)
259    {
260  0 if (av.isRenderGaps())
261    {
262  0 graphics.drawString(seq.getSequenceAsString(start, end + 1), 0, y1);
263    }
264    else
265    {
266  0 char gap = av.getGapCharacter();
267  0 graphics.drawString(
268    seq.getSequenceAsString(start, end + 1).replace(gap, ' '),
269    0, y1);
270    }
271    }
272    else
273    {
274  6193 boolean srep = av.isDisplayReferenceSeq();
275  6193 boolean getboxColour = false;
276  6193 boolean isarep = av.getAlignment().getSeqrep() == seq;
277  6193 Color resBoxColour = Color.white;
278   
279  354523 for (int i = start; i <= end; i++)
280    {
281   
282  348330 graphics.setColor(av.getTextColour());
283  348330 getboxColour = false;
284  348330 s = seq.getCharAt(i);
285   
286  348330 if (!renderGaps && jalview.util.Comparison.isGap(s))
287    {
288  0 continue;
289    }
290   
291  348330 SequenceGroup currentSequenceGroup = resColourFinder
292    .getCurrentSequenceGroup(
293    allGroups, i);
294  348330 if (currentSequenceGroup != null)
295    {
296  264784 if (!currentSequenceGroup.getDisplayText())
297    {
298  0 continue;
299    }
300   
301  264784 if (currentSequenceGroup.thresholdTextColour > 0
302    || currentSequenceGroup.getColourText())
303    {
304  0 getboxColour = true;
305  0 resBoxColour = resColourFinder.getBoxColour(
306    currentSequenceGroup.getGroupColourScheme(), seq,
307    i);
308   
309  0 if (currentSequenceGroup.getColourText())
310    {
311  0 graphics.setColor(resBoxColour.darker());
312    }
313   
314  0 if (currentSequenceGroup.thresholdTextColour > 0)
315    {
316  0 if (resBoxColour.getRed() + resBoxColour.getBlue()
317    + resBoxColour
318    .getGreen() < currentSequenceGroup.thresholdTextColour)
319    {
320  0 graphics.setColor(currentSequenceGroup.textColour2);
321    }
322    }
323    }
324    else
325    {
326  264784 graphics.setColor(currentSequenceGroup.textColour);
327    }
328  264784 boolean isgrep = currentSequenceGroup != null
329    ? currentSequenceGroup.getSeqrep() == seq : false;
330  264784 if (!isarep && !isgrep
331    && currentSequenceGroup.getShowNonconserved()) // todo
332    // optimize
333    {
334    // todo - use sequence group consensus
335  0 s = getDisplayChar(srep, i, s, '.', currentSequenceGroup);
336   
337    }
338   
339    }
340    else
341    {
342  83546 if (!av.getShowText())
343    {
344  0 continue;
345    }
346   
347  83546 if (av.getColourText())
348    {
349  0 getboxColour = true;
350  0 resBoxColour = resColourFinder
351    .getBoxColour(av.getResidueShading(), seq, i);
352   
353  0 if (av.getShowBoxes())
354    {
355  0 graphics.setColor(resBoxColour.darker());
356    }
357    else
358    {
359  0 graphics.setColor(resBoxColour);
360    }
361    }
362   
363  83546 if (av.getThresholdTextColour() > 0)
364    {
365  0 if (!getboxColour)
366    {
367  0 resBoxColour = resColourFinder
368    .getBoxColour(av.getResidueShading(), seq, i);
369    }
370   
371  0 if (resBoxColour.getRed() + resBoxColour.getBlue()
372    + resBoxColour.getGreen() < av.getThresholdTextColour())
373    {
374  0 graphics.setColor(av.getTextColour2());
375    }
376    }
377  83546 if (!isarep && av.getShowUnconserved())
378    {
379  0 s = getDisplayChar(srep, i, s, '.', null);
380   
381    }
382   
383    }
384   
385  348330 charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
386  348330 graphics.drawString(String.valueOf(s),
387    charOffset + av.getCharWidth() * (i - start), y1);
388   
389    }
390    }
391    }
392   
393    /**
394    * Returns 'conservedChar' to represent the given position if the sequence
395    * character at that position is equal to the consensus (ignoring case), else
396    * returns the sequence character
397    *
398    * @param usesrep
399    * @param position
400    * @param sequenceChar
401    * @param conservedChar
402    * @return
403    */
 
404  0 toggle private char getDisplayChar(final boolean usesrep, int position,
405    char sequenceChar, char conservedChar, SequenceGroup currentGroup)
406    {
407    // TODO - use currentSequenceGroup rather than alignment
408    // currentSequenceGroup.getConsensus()
409  0 char conschar = (usesrep) ? (currentGroup == null
410    || position < currentGroup.getStartRes()
411    || position > currentGroup.getEndRes()
412    ? av.getAlignment().getSeqrep().getCharAt(position)
413  0 : (currentGroup.getSeqrep() != null
414    ? currentGroup.getSeqrep().getCharAt(position)
415    : av.getAlignment().getSeqrep()
416    .getCharAt(position)))
417  0 : (currentGroup != null && currentGroup.getConsensus() != null
418    && position >= currentGroup.getStartRes()
419    && position <= currentGroup.getEndRes()
420    && currentGroup
421    .getConsensus().annotations.length > position)
422    ? currentGroup
423    .getConsensus().annotations[position].displayCharacter
424    .charAt(0)
425    : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
426    .charAt(0);
427  0 if (!jalview.util.Comparison.isGap(conschar)
428    && (sequenceChar == conschar
429    || sequenceChar + CHAR_TO_UPPER == conschar))
430    {
431  0 sequenceChar = conservedChar;
432    }
433  0 return sequenceChar;
434    }
435   
436    /**
437    * DOCUMENT ME!
438    *
439    * @param seq
440    * DOCUMENT ME!
441    * @param start
442    * DOCUMENT ME!
443    * @param end
444    * DOCUMENT ME!
445    * @param x1
446    * DOCUMENT ME!
447    * @param y1
448    * DOCUMENT ME!
449    * @param width
450    * DOCUMENT ME!
451    * @param height
452    * DOCUMENT ME!
453    */
 
454  3 toggle public void drawHighlightedText(SequenceI seq, int start, int end, int x1,
455    int y1)
456    {
457  3 int pady = av.getCharHeight() / 5;
458  3 int charOffset = 0;
459  3 graphics.setColor(Color.BLACK);
460  3 graphics.fillRect(x1, y1, av.getCharWidth() * (end - start + 1),
461    av.getCharHeight());
462  3 graphics.setColor(Color.white);
463   
464  3 char s = '~';
465   
466    // Need to find the sequence position here.
467  3 if (av.isValidCharWidth())
468    {
469  18 for (int i = start; i <= end; i++)
470    {
471  15 if (i < seq.getLength())
472    {
473  15 s = seq.getCharAt(i);
474    }
475   
476  15 charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
477  15 graphics.drawString(String.valueOf(s),
478    charOffset + x1 + (av.getCharWidth() * (i - start)),
479    (y1 + av.getCharHeight()) - pady);
480    }
481    }
482    }
483   
484    /**
485    * Draw a sequence canvas cursor
486    *
487    * @param g
488    * graphics context to draw on
489    * @param s
490    * character to draw at cursor
491    * @param x1
492    * x position of cursor in graphics context
493    * @param y1
494    * y position of cursor in graphics context
495    */
 
496  0 toggle public void drawCursor(Graphics g, char s, int x1, int y1)
497    {
498  0 int pady = av.getCharHeight() / 5;
499  0 int charOffset = 0;
500  0 g.setColor(Color.black);
501  0 g.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight());
502   
503  0 if (av.isValidCharWidth())
504    {
505  0 g.setColor(Color.white);
506  0 charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2;
507  0 g.drawString(String.valueOf(s), charOffset + x1,
508    (y1 + av.getCharHeight()) - pady);
509    }
510   
511    }
512    }