new Implementation for getting colour quickly
[jalview.git] / src / jalview / gui / SequenceRenderer.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import jalview.schemes.*;\r
24 \r
25 import java.awt.*;\r
26 import java.awt.image.BufferedImage;\r
27 \r
28 \r
29 /**\r
30  * DOCUMENT ME!\r
31  *\r
32  * @author $author$\r
33  * @version $Revision$\r
34  */\r
35 public class SequenceRenderer\r
36 {\r
37     AlignViewport av;\r
38     FontMetrics fm;\r
39     boolean renderGaps = true;\r
40     SequenceGroup currentSequenceGroup = null;\r
41     SequenceGroup[] allGroups = null;\r
42     Color resBoxColour;\r
43     Graphics graphics;\r
44 \r
45     /**\r
46      * Creates a new SequenceRenderer object.\r
47      *\r
48      * @param av DOCUMENT ME!\r
49      */\r
50     public SequenceRenderer(AlignViewport av)\r
51     {\r
52         this.av = av;\r
53     }\r
54 \r
55     /**\r
56      * DOCUMENT ME!\r
57      *\r
58      * @param b DOCUMENT ME!\r
59      */\r
60     public void renderGaps(boolean b)\r
61     {\r
62         renderGaps = b;\r
63     }\r
64 \r
65 \r
66     public Color getResidueBoxColour(SequenceI seq, int i)\r
67     {\r
68       allGroups = av.alignment.findAllGroups(seq);\r
69 \r
70       if (inCurrentSequenceGroup(i))\r
71       {\r
72         if (currentSequenceGroup.getDisplayBoxes())\r
73         {\r
74           getBoxColour(currentSequenceGroup.cs, seq, i);\r
75         }\r
76       }\r
77       else if (av.getShowBoxes())\r
78       {\r
79           getBoxColour(av.globalColourScheme, seq, i);\r
80       }\r
81 \r
82       return resBoxColour;\r
83     }\r
84 \r
85 \r
86     /**\r
87      * DOCUMENT ME!\r
88      *\r
89      * @param cs DOCUMENT ME!\r
90      * @param seq DOCUMENT ME!\r
91      * @param i DOCUMENT ME!\r
92      */\r
93     void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)\r
94     {\r
95         if (cs != null)\r
96         {\r
97             resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);\r
98         }\r
99         else\r
100         {\r
101             resBoxColour = Color.white;\r
102         }\r
103     }\r
104 \r
105     /**\r
106      * DOCUMENT ME!\r
107      *\r
108      * @param g DOCUMENT ME!\r
109      * @param seq DOCUMENT ME!\r
110      * @param sg DOCUMENT ME!\r
111      * @param start DOCUMENT ME!\r
112      * @param end DOCUMENT ME!\r
113      * @param x1 DOCUMENT ME!\r
114      * @param y1 DOCUMENT ME!\r
115      * @param width DOCUMENT ME!\r
116      * @param height DOCUMENT ME!\r
117      */\r
118     public void drawSequence(Graphics g, SequenceI seq, SequenceGroup[] sg,\r
119         int start, int end, int x1, int y1, int width, int height)\r
120     {\r
121         allGroups = sg;\r
122 \r
123         graphics = g;\r
124 \r
125         drawBoxes(seq, start, end, x1, y1, (int) width, height);\r
126 \r
127         fm = g.getFontMetrics();\r
128         drawText(seq, start, end, x1, y1, (int) width, height);\r
129     }\r
130 \r
131     /**\r
132      * DOCUMENT ME!\r
133      *\r
134      * @param seq DOCUMENT ME!\r
135      * @param start DOCUMENT ME!\r
136      * @param end DOCUMENT ME!\r
137      * @param x1 DOCUMENT ME!\r
138      * @param y1 DOCUMENT ME!\r
139      * @param width DOCUMENT ME!\r
140      * @param height DOCUMENT ME!\r
141      */\r
142     public synchronized void drawBoxes(SequenceI seq, int start, int end, int x1, int y1,\r
143         int width, int height)\r
144     {\r
145       int i = start;\r
146       int length = seq.getLength();\r
147 \r
148       int curStart = -1;\r
149       int curWidth = width;\r
150 \r
151       Color tempColour = null;\r
152 \r
153       while (i <= end)\r
154       {\r
155         resBoxColour = Color.white;\r
156 \r
157         if (i < length)\r
158         {\r
159           if (inCurrentSequenceGroup(i))\r
160           {\r
161             if (currentSequenceGroup.getDisplayBoxes())\r
162             {\r
163               getBoxColour(currentSequenceGroup.cs, seq, i);\r
164             }\r
165           }\r
166           else if (av.getShowBoxes())\r
167           {\r
168             getBoxColour(av.globalColourScheme, seq, i);\r
169           }\r
170 \r
171         }\r
172 \r
173           if (resBoxColour != tempColour)\r
174           {\r
175               if (tempColour != null)\r
176               {\r
177                   graphics.fillRect(x1 + (width * (curStart - start)), y1,\r
178                       curWidth, height);\r
179               }\r
180 \r
181               graphics.setColor(resBoxColour);\r
182 \r
183               curStart = i;\r
184               curWidth = width;\r
185               tempColour = resBoxColour;\r
186           }\r
187           else\r
188           {\r
189               curWidth += width;\r
190           }\r
191 \r
192           i++;\r
193       }\r
194 \r
195       graphics.fillRect(x1 + (width * (curStart - start)), y1, curWidth,\r
196           height);\r
197 \r
198     }\r
199 \r
200     /**\r
201      * DOCUMENT ME!\r
202      *\r
203      * @param seq DOCUMENT ME!\r
204      * @param start DOCUMENT ME!\r
205      * @param end DOCUMENT ME!\r
206      * @param x1 DOCUMENT ME!\r
207      * @param y1 DOCUMENT ME!\r
208      * @param width DOCUMENT ME!\r
209      * @param height DOCUMENT ME!\r
210      */\r
211     public void drawText(SequenceI seq, int start, int end, int x1, int y1,\r
212         int width, int height)\r
213     {\r
214         int pady = height / 5;\r
215         int charOffset = 0;\r
216         char s;\r
217 \r
218 \r
219         // Need to find the sequence position here.\r
220         String sequence = seq.getSequence();\r
221 \r
222         if(end+1>=seq.getLength())\r
223           end = seq.getLength()-1;\r
224 \r
225         for (int i = start; i <= end; i++)\r
226         {\r
227             graphics.setColor(Color.black);\r
228 \r
229             s = sequence.charAt(i);\r
230 \r
231             if (!renderGaps && jalview.util.Comparison.isGap(s))\r
232             {\r
233                 continue;\r
234             }\r
235 \r
236             if (inCurrentSequenceGroup(i))\r
237             {\r
238                 if (!currentSequenceGroup.getDisplayText())\r
239                 {\r
240                     continue;\r
241                 }\r
242 \r
243                 if (currentSequenceGroup.getColourText())\r
244                 {\r
245                     getBoxColour(currentSequenceGroup.cs, seq, i);\r
246                     graphics.setColor(resBoxColour.darker());\r
247                 }\r
248             }\r
249             else\r
250             {\r
251                 if (!av.getShowText())\r
252                 {\r
253                     continue;\r
254                 }\r
255 \r
256                 if (av.getColourText())\r
257                 {\r
258                     getBoxColour(av.globalColourScheme, seq, i);\r
259 \r
260                     if (av.getShowBoxes())\r
261                     {\r
262                         graphics.setColor(resBoxColour.darker());\r
263                     }\r
264                     else\r
265                     {\r
266                         graphics.setColor(resBoxColour);\r
267                     }\r
268                 }\r
269             }\r
270 \r
271             charOffset = (width - fm.charWidth(s)) / 2;\r
272             graphics.drawString(String.valueOf(s),\r
273                 charOffset + x1 + (int)(width * (i - start)), (y1 + height) - pady);\r
274 \r
275         }\r
276     }\r
277 \r
278     /**\r
279      * DOCUMENT ME!\r
280      *\r
281      * @param res DOCUMENT ME!\r
282      *\r
283      * @return DOCUMENT ME!\r
284      */\r
285     boolean inCurrentSequenceGroup(int res)\r
286     {\r
287         if (allGroups == null)\r
288         {\r
289             return false;\r
290         }\r
291 \r
292         for (int i = 0; i < allGroups.length; i++)\r
293         {\r
294             if ((allGroups[i].getStartRes() <= res) &&\r
295                     (allGroups[i].getEndRes() >= res))\r
296             {\r
297                 currentSequenceGroup = allGroups[i];\r
298 \r
299                 return true;\r
300             }\r
301         }\r
302 \r
303         return false;\r
304     }\r
305 \r
306     /**\r
307      * DOCUMENT ME!\r
308      *\r
309      * @param seq DOCUMENT ME!\r
310      * @param start DOCUMENT ME!\r
311      * @param end DOCUMENT ME!\r
312      * @param x1 DOCUMENT ME!\r
313      * @param y1 DOCUMENT ME!\r
314      * @param width DOCUMENT ME!\r
315      * @param height DOCUMENT ME!\r
316      */\r
317     public void drawHighlightedText(SequenceI seq, int start, int end, int x1,\r
318         int y1, int width, int height)\r
319     {\r
320         int pady = height / 5;\r
321         int charOffset = 0;\r
322         graphics.setColor(Color.BLACK);\r
323         graphics.fillRect(x1, y1, width * (end - start + 1), height);\r
324         graphics.setColor(Color.white);\r
325 \r
326         char s = '~';\r
327 \r
328         // Need to find the sequence position here.\r
329         for (int i = start; i <= end; i++)\r
330         {\r
331             if (i < seq.getLength())\r
332             {\r
333                 s = seq.getSequence().charAt(i);\r
334             }\r
335 \r
336             charOffset = (width - fm.charWidth(s)) / 2;\r
337             graphics.drawString(String.valueOf(s),\r
338                 charOffset + x1 + (width * (i - start)), (y1 + height) - pady);\r
339         }\r
340     }\r
341 }\r