Formatting
[jalview.git] / src / jalview / appletgui / SequenceRenderer.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.awt.*;\r
23 \r
24 import jalview.datamodel.*;\r
25 import jalview.schemes.*;\r
26 \r
27 public class SequenceRenderer\r
28 {\r
29   AlignViewport av;\r
30   FontMetrics fm;\r
31   boolean renderGaps = true;\r
32   SequenceGroup currentSequenceGroup = null;\r
33   SequenceGroup[] allGroups = null;\r
34   Color resBoxColour;\r
35   Graphics graphics;\r
36   boolean forOverview = false;\r
37 \r
38   public SequenceRenderer(AlignViewport av)\r
39   {\r
40     this.av = av;\r
41   }\r
42 \r
43   /**\r
44    * DOCUMENT ME!\r
45    *\r
46    * @param b DOCUMENT ME!\r
47    */\r
48   public void prepare(Graphics g, boolean renderGaps)\r
49   {\r
50     graphics = g;\r
51     fm = g.getFontMetrics();\r
52 \r
53     this.renderGaps = renderGaps;\r
54   }\r
55 \r
56   public Color getResidueBoxColour(SequenceI seq, int i)\r
57   {\r
58     allGroups = av.alignment.findAllGroups(seq);\r
59 \r
60     if (inCurrentSequenceGroup(i))\r
61     {\r
62       if (currentSequenceGroup.getDisplayBoxes())\r
63       {\r
64         getBoxColour(currentSequenceGroup.cs, seq, i);\r
65       }\r
66     }\r
67     else if (av.getShowBoxes())\r
68     {\r
69       getBoxColour(av.globalColourScheme, seq, i);\r
70     }\r
71 \r
72     return resBoxColour;\r
73   }\r
74 \r
75   void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)\r
76   {\r
77     if (cs != null)\r
78     {\r
79       resBoxColour = cs.findColour(seq.getCharAt(i), i);\r
80     }\r
81     else if (forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i)))\r
82     {\r
83       resBoxColour = Color.lightGray;\r
84     }\r
85     else\r
86     {\r
87       resBoxColour = Color.white;\r
88     }\r
89 \r
90   }\r
91 \r
92   public Color findSequenceColour(SequenceI seq, int i)\r
93   {\r
94     allGroups = av.alignment.findAllGroups(seq);\r
95     drawBoxes(seq, i, i, 0);\r
96     return resBoxColour;\r
97   }\r
98 \r
99   public void drawSequence(SequenceI seq, SequenceGroup[] sg,\r
100                            int start, int end, int y1)\r
101   {\r
102     if (seq == null)\r
103     {\r
104       return;\r
105     }\r
106 \r
107     allGroups = sg;\r
108 \r
109     drawBoxes(seq, start, end, y1);\r
110 \r
111     if (av.validCharWidth)\r
112     {\r
113       drawText(seq, start, end, y1);\r
114     }\r
115   }\r
116 \r
117   public void drawBoxes(SequenceI seq, int start, int end, int y1)\r
118   {\r
119     int i = start;\r
120     int length = seq.getLength();\r
121 \r
122     int curStart = -1;\r
123     int curWidth = av.charWidth;\r
124 \r
125     Color tempColour = null;\r
126     while (i <= end)\r
127     {\r
128       resBoxColour = Color.white;\r
129       if (i < length)\r
130       {\r
131         if (inCurrentSequenceGroup(i))\r
132         {\r
133           if (currentSequenceGroup.getDisplayBoxes())\r
134           {\r
135             getBoxColour(currentSequenceGroup.cs, seq, i);\r
136           }\r
137         }\r
138         else if (av.getShowBoxes())\r
139         {\r
140           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
141         }\r
142       }\r
143 \r
144       if (resBoxColour != tempColour)\r
145       {\r
146         if (tempColour != null)\r
147         {\r
148           graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,\r
149                             av.charHeight);\r
150         }\r
151         graphics.setColor(resBoxColour);\r
152 \r
153         curStart = i;\r
154         curWidth = av.charWidth;\r
155         tempColour = resBoxColour;\r
156 \r
157       }\r
158       else\r
159       {\r
160         curWidth += av.charWidth;\r
161       }\r
162 \r
163       i++;\r
164     }\r
165 \r
166     graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth,\r
167                       av.charHeight);\r
168   }\r
169 \r
170   public void drawText(SequenceI seq, int start, int end, int y1)\r
171   {\r
172     Font boldFont = null;\r
173     boolean bold = false;\r
174     if (av.upperCasebold)\r
175     {\r
176       boldFont = new Font(av.getFont().getName(), Font.BOLD, av.charHeight);\r
177 \r
178       graphics.setFont(av.getFont());\r
179     }\r
180 \r
181     y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady\r
182 \r
183     int charOffset = 0;\r
184 \r
185     // Need to find the sequence position here.\r
186     if (end + 1 >= seq.getLength())\r
187     {\r
188       end = seq.getLength() - 1;\r
189     }\r
190 \r
191     char s = ' ';\r
192 \r
193     for (int i = start; i <= end; i++)\r
194     {\r
195       graphics.setColor(Color.black);\r
196 \r
197       s = seq.getCharAt(i);\r
198       if (!renderGaps && jalview.util.Comparison.isGap(s))\r
199       {\r
200         continue;\r
201       }\r
202 \r
203       if (inCurrentSequenceGroup(i))\r
204       {\r
205         if (!currentSequenceGroup.getDisplayText())\r
206         {\r
207           continue;\r
208         }\r
209 \r
210         if (currentSequenceGroup.getColourText())\r
211         {\r
212           getBoxColour(currentSequenceGroup.cs, seq, i);\r
213           graphics.setColor(resBoxColour.darker());\r
214         }\r
215       }\r
216       else\r
217       {\r
218         if (!av.getShowText())\r
219         {\r
220           continue;\r
221         }\r
222 \r
223         if (av.getColourText())\r
224         {\r
225           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
226           if (av.getShowBoxes())\r
227           {\r
228             graphics.setColor(resBoxColour.darker());\r
229           }\r
230           else\r
231           {\r
232             graphics.setColor(resBoxColour);\r
233           }\r
234         }\r
235       }\r
236 \r
237       if (av.upperCasebold)\r
238       {\r
239         fm = graphics.getFontMetrics();\r
240         if ('A' <= s && s <= 'Z')\r
241         {\r
242           if (!bold)\r
243           {\r
244 \r
245             graphics.setFont(boldFont);\r
246           }\r
247           bold = true;\r
248         }\r
249         else if (bold)\r
250         {\r
251           graphics.setFont(av.font);\r
252           bold = false;\r
253         }\r
254 \r
255       }\r
256 \r
257       charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
258       graphics.drawString(String.valueOf(s),\r
259                           charOffset + av.charWidth * (i - start),\r
260                           y1);\r
261     }\r
262 \r
263   }\r
264 \r
265   boolean inCurrentSequenceGroup(int res)\r
266   {\r
267     if (allGroups == null)\r
268     {\r
269       return false;\r
270     }\r
271 \r
272     for (int i = 0; i < allGroups.length; i++)\r
273     {\r
274       if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)\r
275       {\r
276         currentSequenceGroup = allGroups[i];\r
277         return true;\r
278       }\r
279     }\r
280 \r
281     return false;\r
282   }\r
283 \r
284   public void drawHighlightedText(SequenceI seq, int start, int end, int x1,\r
285                                   int y1)\r
286   {\r
287     int pady = av.charHeight / 5;\r
288     int charOffset = 0;\r
289     graphics.setColor(Color.black);\r
290     graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), av.charHeight);\r
291     graphics.setColor(Color.white);\r
292 \r
293     char s = '~';\r
294     // Need to find the sequence position here.\r
295     if (av.validCharWidth)\r
296     {\r
297       for (int i = start; i <= end; i++)\r
298       {\r
299         if (i < seq.getLength())\r
300         {\r
301           s = seq.getCharAt(i);\r
302         }\r
303 \r
304         charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
305         graphics.drawString(String.valueOf(s),\r
306                             charOffset + x1 + av.charWidth * (i - start),\r
307                             y1 + av.charHeight - pady);\r
308       }\r
309     }\r
310   }\r
311 \r
312   public void drawCursor(SequenceI seq, int res, int x1, int y1)\r
313   {\r
314     int pady = av.charHeight / 5;\r
315     int charOffset = 0;\r
316     graphics.setColor(Color.black);\r
317     graphics.fillRect(x1, y1, av.charWidth, av.charHeight);\r
318     graphics.setColor(Color.white);\r
319 \r
320     graphics.setColor(Color.white);\r
321 \r
322     char s = seq.getCharAt(res);\r
323     if (av.validCharWidth)\r
324     {\r
325 \r
326       charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
327       graphics.drawString(String.valueOf(s),\r
328                           charOffset + x1,\r
329                           (y1 + av.charHeight) - pady);\r
330     }\r
331   }\r
332 \r
333 }\r