Faster painting
[jalview.git] / src / jalview / appletgui / 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 \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 \r
37   public SequenceRenderer(AlignViewport av)\r
38   {\r
39     this.av = av;\r
40   }\r
41 \r
42   public void renderGaps(boolean b)\r
43   {\r
44     renderGaps = b;\r
45   }\r
46 \r
47   public Color getResidueBoxColour(SequenceI seq, int i)\r
48   {\r
49     allGroups = av.alignment.findAllGroups(seq);\r
50 \r
51     if (inCurrentSequenceGroup(i))\r
52     {\r
53       if (currentSequenceGroup.getDisplayBoxes())\r
54       {\r
55         getBoxColour(currentSequenceGroup.cs, seq, i);\r
56       }\r
57     }\r
58     else if (av.getShowBoxes())\r
59     {\r
60         getBoxColour(av.globalColourScheme, seq, i);\r
61     }\r
62 \r
63     return resBoxColour;\r
64     }\r
65 \r
66   void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)\r
67   {\r
68     if (cs != null)\r
69     {\r
70       resBoxColour = cs.findColour(seq.getSequence(i, i + 1), i);\r
71     }\r
72     else\r
73     {\r
74       resBoxColour = Color.white;\r
75     }\r
76   }\r
77 \r
78   public Color findSequenceColour(SequenceI seq, int i)\r
79   {\r
80     allGroups = av.alignment.findAllGroups(seq);\r
81     drawBoxes(seq, i,i, 0, 0, 1,1);\r
82     return resBoxColour;\r
83   }\r
84 \r
85   public void drawSequence(Graphics g, SequenceI seq, SequenceGroup[] sg,\r
86                            int start, int end, int x1, int y1, int width,\r
87                            int height)\r
88   {\r
89     allGroups = sg;\r
90 \r
91     graphics = g;\r
92 \r
93     drawBoxes(seq, start, end, x1, y1, (int) width, height);\r
94 \r
95     fm = g.getFontMetrics();\r
96     drawText(seq, start, end, x1, y1, (int) width, height);\r
97 \r
98   }\r
99 \r
100   public void drawBoxes(SequenceI seq, int start, int end, int x1, int y1,\r
101                         int width, int height)\r
102   {\r
103     int i = start;\r
104     int length = seq.getLength();\r
105 \r
106     int curStart = -1;\r
107     int curWidth = width;\r
108 \r
109     Color tempColour = null;\r
110     while (i <= end)\r
111     {\r
112       resBoxColour = Color.white;\r
113       if(i < length)\r
114       {\r
115         if (inCurrentSequenceGroup(i))\r
116         {\r
117           if (currentSequenceGroup.getDisplayBoxes())\r
118           {\r
119             getBoxColour(currentSequenceGroup.cs, seq, i);\r
120           }\r
121         }\r
122         else if (av.getShowBoxes())\r
123         {\r
124           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
125         }\r
126       }\r
127 \r
128 \r
129       if (resBoxColour != tempColour)\r
130       {\r
131         if (tempColour != null)\r
132         {\r
133           graphics.fillRect(x1 + width * (curStart - start), y1, curWidth,\r
134                             height);\r
135         }\r
136         graphics.setColor(resBoxColour);\r
137 \r
138         curStart = i;\r
139         curWidth = width;\r
140         tempColour = resBoxColour;\r
141 \r
142       }\r
143       else\r
144       {\r
145         curWidth += width;\r
146       }\r
147 \r
148       i++;\r
149     }\r
150 \r
151     graphics.fillRect(x1 + width * (curStart - start), y1, curWidth, height);\r
152   }\r
153 \r
154   public void drawText(SequenceI seq, int start, int end, int x1, int y1,\r
155                        int width, int height)\r
156   {\r
157 \r
158     y1 += height - height / 5;  // height/5 replaces pady\r
159 \r
160     int charOffset = 0;\r
161 \r
162     // Need to find the sequence position here.\r
163     if(end+1>=seq.getLength())\r
164           end = seq.getLength()-1;\r
165 \r
166     char s = ' ';\r
167 \r
168     for (int i = start; i <= end; i++)\r
169     {\r
170       graphics.setColor(Color.black);\r
171 \r
172       s = seq.getCharAt(i);\r
173       if (!renderGaps && jalview.util.Comparison.isGap(s))\r
174       {\r
175         continue;\r
176       }\r
177 \r
178       if (inCurrentSequenceGroup(i))\r
179       {\r
180         if (!currentSequenceGroup.getDisplayText())\r
181         {\r
182           continue;\r
183         }\r
184 \r
185         if (currentSequenceGroup.getColourText())\r
186         {\r
187           getBoxColour(currentSequenceGroup.cs, seq, i);\r
188           graphics.setColor(resBoxColour.darker());\r
189         }\r
190       }\r
191       else\r
192       {\r
193         if (!av.getShowText())\r
194         {\r
195           continue;\r
196         }\r
197 \r
198         if (av.getColourText())\r
199         {\r
200           getBoxColour(av.getGlobalColourScheme(), seq, i);\r
201           if (av.getShowBoxes())\r
202           {\r
203             graphics.setColor(resBoxColour.darker());\r
204           }\r
205           else\r
206           {\r
207             graphics.setColor(resBoxColour);\r
208           }\r
209         }\r
210       }\r
211 \r
212       charOffset = (width - fm.charWidth(s)) / 2;\r
213       graphics.drawString(String.valueOf(s),\r
214                          charOffset + x1 + width * (i - start),\r
215                         y1 );\r
216     }\r
217 \r
218   }\r
219 \r
220   boolean inCurrentSequenceGroup(int res)\r
221   {\r
222     if (allGroups == null)\r
223     {\r
224       return false;\r
225     }\r
226 \r
227     for (int i = 0; i < allGroups.length; i++)\r
228     {\r
229       if (allGroups[i].getStartRes() <= res && allGroups[i].getEndRes() >= res)\r
230       {\r
231         currentSequenceGroup = allGroups[i];\r
232         return true;\r
233       }\r
234     }\r
235 \r
236     return false;\r
237   }\r
238 \r
239   public void drawHighlightedText(SequenceI seq, int start, int end, int x1,\r
240                                   int y1, int width, int height)\r
241   {\r
242     int pady = height / 5;\r
243     int charOffset = 0;\r
244     graphics.setColor(Color.black);\r
245     graphics.fillRect(x1, y1, width * (end - start + 1), height);\r
246     graphics.setColor(Color.white);\r
247 \r
248     char s = '~';\r
249     // Need to find the sequence position here.\r
250     for (int i = start; i <= end; i++)\r
251     {\r
252       if (i < seq.getLength())\r
253       {\r
254         s = seq.getSequence().charAt(i);\r
255       }\r
256 \r
257       charOffset = (width - fm.charWidth(s)) / 2;\r
258       graphics.drawString(String.valueOf(s),\r
259                           charOffset + x1 + width * (i - start),\r
260                           y1 + height - pady);\r
261     }\r
262   }\r
263 \r
264 }\r