JAL-3026 srcjar files for VARNA and log4j
[jalview.git] / srcjar / fr / orsay / lri / varna / models / export / SecStrDrawingProducer.java
1 /*
2  VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3  Copyright (C) 2008  Kevin Darty, Alain Denise and Yann Ponty.
4  electronic mail : Yann.Ponty@lri.fr
5  paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
6
7  This file is part of VARNA version 3.1.
8  VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10
11  VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16  If not, see http://www.gnu.org/licenses.
17  */
18 package fr.orsay.lri.varna.models.export;
19
20 import java.awt.Color;
21 import java.awt.geom.AffineTransform;
22 import java.awt.geom.GeneralPath;
23 import java.awt.geom.PathIterator;
24 import java.awt.geom.Point2D;
25 import java.awt.geom.Rectangle2D;
26 import java.util.Vector;
27
28 import fr.orsay.lri.varna.models.rna.ModeleBP;
29
30 public abstract class SecStrDrawingProducer {
31         public static final int FONT_TIMES_ROMAN = 0;
32         public static final int FONT_TIMES_BOLD = 1;
33         public static final int FONT_TIMES_ITALIC = 2;
34         public static final int FONT_TIMES_BOLD_ITALIC = 3;
35         public static final int FONT_HELVETICA = 16;
36         public static final int FONT_HELVETICA_OBLIQUE = 17;
37         public static final int FONT_HELVETICA_BOLD = 18;
38         public static final int FONT_HELVETICA_BOLD_OBLIQUE = 19;
39         public static final int FONT_COURIER = 12;
40         public static final int FONT_COURIER_BOLD = 13;
41         public static final int FONT_COURIER_OBLIQUE = 14;
42         public static final int FONT_COURIER_BOLD_OBLIQUE = 15;
43
44         private Vector<GraphicElement> _commands = new Vector<GraphicElement>();
45
46         private double _scale = 1.0;
47         private double _xmin = Double.MAX_VALUE;
48         private double _ymin = Double.MAX_VALUE;
49         private double _xmax = -Double.MAX_VALUE;
50         private double _ymax = -Double.MAX_VALUE;
51
52         protected Color _curColor = Color.black;
53         protected Color _backgroundColor = null;
54         
55         protected double _fontsize = 10.0;
56         protected int _font = FONT_HELVETICA_BOLD;
57
58         
59         public Color getCurrentColor() {
60                 return _curColor;
61         }
62
63         public double getCurFontSize() {
64                 return _fontsize;
65         }
66
67         public int getCurrentFont() {
68                 return _font;
69         }
70         
71
72         public abstract String drawBaseStartS(int index);
73         public abstract String drawBaseEndS(int index);
74         public abstract String drawBasePairStartS(int i, int j, ModeleBP bps);
75         public abstract String drawBasePairEndS(int index);
76         public abstract String drawBackboneStartS(int i, int j);
77         public abstract String drawBackboneEndS(int index);
78
79         public abstract String drawLineS(Point2D.Double orig,
80                         Point2D.Double dest, double thickness);
81
82         
83         public abstract String drawArcS(Point2D.Double origine, double width,
84                         double height, double startAngle, double endAngle);
85
86         public abstract String drawTextS(Point2D.Double base, String txt);
87
88         public abstract String drawRectangleS(Point2D.Double orig,
89                         Point2D.Double dims, double thickness);
90         
91         public abstract String drawCircleS(Point2D.Double base, double radius,
92                         double thickness);
93
94         public abstract String fillCircleS(Point2D.Double base, double radius,
95                         double thickness, Color color);
96
97         public abstract String drawPolygonS(Point2D.Double[] points,
98                         double thickness);
99
100         public abstract String fillPolygonS(Point2D.Double[] points,
101                  Color color);
102
103         public abstract String setFontS(int font, double size);
104
105         public String setColorS(Color col) {
106                 _curColor = col;
107                 return "";
108         }
109
110         public abstract String headerS(Rectangle2D.Double bb);
111
112         public abstract String footerS();
113
114         @SuppressWarnings("unused")
115         private void resetBoundingBox() {
116                 _xmin = Double.MAX_VALUE;
117                 _ymin = Double.MAX_VALUE;
118                 _xmax = -Double.MAX_VALUE;
119                 _ymax = -Double.MAX_VALUE;
120         }
121
122         private void updateBoundingBox(double x, double y) {
123                 _xmin = Math.min(_xmin, x - 10);
124                 _ymin = Math.min(_ymin, y - 10);
125                 _xmax = Math.max(_xmax, x + 10);
126                 _ymax = Math.max(_ymax, y + 10);
127         }
128
129         public void drawLine(double x0, double y0, double x1, double y1,
130                         double thickness) {
131                 updateBoundingBox(x0, y0);
132                 updateBoundingBox(x1, y1);
133                 _commands.add(new LineCommand(new Point2D.Double(x0, y0),
134                                 new Point2D.Double(x1, y1), thickness));
135         }
136
137         public void drawArc(Point2D.Double origine, double width, double height,
138                         double startAngle, double endAngle) {
139                 updateBoundingBox(origine.x + width/2., origine.y + height/2.);
140                 updateBoundingBox(origine.x - width/2., origine.y - height/2.);
141                 _commands.add(new ArcCommand(origine, width, height, startAngle,
142                                 endAngle));
143         }
144
145         public void drawText(double x, double y, String txt) {
146                 updateBoundingBox(x, y);
147
148                 _commands.add(new TextCommand(new Point2D.Double(x, y), new String(txt)));
149         }
150
151         public void drawRectangle(double x, double y, double w, double h,
152                         double thickness) {
153                 updateBoundingBox(x, y);
154                 updateBoundingBox(x + w, y + h);
155
156                 _commands.add(new RectangleCommand(new Point2D.Double(x, y),
157                                 new Point2D.Double(w, h), thickness));
158         }
159         
160         public void fillRectangle(double x, double y, double w, double h, Color color) {
161                 double [] xtab = new double[4];
162                 double [] ytab = new double[4];
163                 xtab[0] = x;
164                 xtab[1] = x+w;
165                 xtab[2] = x+w;
166                 xtab[3] = x;
167                 ytab[0] = y;
168                 ytab[1] = y;
169                 ytab[2] = y+h;
170                 ytab[3] = y+h;
171                 fillPolygon(xtab, ytab, color);
172         }
173
174         public void drawCircle(double x, double y, double radius, double thickness) {
175                 updateBoundingBox(x - radius, y - radius);
176                 updateBoundingBox(x + radius, y + radius);
177
178                 _commands.add(new CircleCommand(new Point2D.Double(x, y), radius,
179                                 thickness));
180
181         }
182
183         public void setColor(Color col) {
184                 _curColor = col;
185                 _commands.add(new ColorCommand(col));
186         }
187         
188         public void setBackgroundColor(Color col){
189                 _backgroundColor = col;
190         }
191
192         public void removeBackgroundColor(){
193                 _backgroundColor = null;
194         }
195
196         public void fillCircle(double x, double y, double radius, double thickness,
197                         Color color) {
198                 updateBoundingBox(x - radius, y - radius);
199                 updateBoundingBox(x + radius, y + radius);
200
201                 _commands.add(new FillCircleCommand(new Point2D.Double(x, y), radius,
202                                 thickness, color));
203         }
204
205         public void drawPolygon(double[] xtab, double[] ytab, double thickness) {
206                 if (xtab.length == ytab.length) {
207                         Point2D.Double points[] = new Point2D.Double[xtab.length];
208                         for (int i = 0; i < xtab.length; i++) {
209                                 points[i] = new Point2D.Double(xtab[i], ytab[i]);
210                                 updateBoundingBox(xtab[i], ytab[i]);
211                         }
212                         _commands.add(new PolygonCommand(points, thickness));
213                 }
214         }
215
216         public void drawPolygon(GeneralPath p, 
217                         double thickness) {
218                 PathIterator pi = p.getPathIterator(null);
219                 Vector<Point2D.Double> v = new Vector<Point2D.Double>();  
220                 double[] coords = new double[6];
221                 while (!pi.isDone())
222                 {
223                         int code = pi.currentSegment(coords);
224                         if (code == PathIterator.SEG_MOVETO)
225                         { v.add(new Point2D.Double(coords[0],coords[1])); }
226                         if (code == PathIterator.SEG_LINETO)
227                         { v.add(new Point2D.Double(coords[0],coords[1])); }                     
228                         pi.next();
229                 }
230                 double[] xtab = new double[v.size()];
231                 double[] ytab = new double[v.size()];
232                 for(int i=0;i<v.size();i++)
233                 {
234                         xtab[i] = v.get(i).x;
235                         ytab[i] = v.get(i).y;
236                 }
237                 drawPolygon(xtab,ytab, thickness);
238         }
239
240                 
241         public void fillPolygon(GeneralPath p, 
242                         Color color) {
243                 PathIterator pi = p.getPathIterator(null);
244                 Vector<Point2D.Double> v = new Vector<Point2D.Double>();  
245                 double[] coords = new double[6];
246                 while (!pi.isDone())
247                 {
248                         int code = pi.currentSegment(coords);
249                         if (code == PathIterator.SEG_MOVETO)
250                         { v.add(new Point2D.Double(coords[0],coords[1])); }
251                         if (code == PathIterator.SEG_LINETO)
252                         { v.add(new Point2D.Double(coords[0],coords[1])); }                     
253                         pi.next();
254                 }
255                 double[] xtab = new double[v.size()];
256                 double[] ytab = new double[v.size()];
257                 for(int i=0;i<v.size();i++)
258                 {
259                         xtab[i] = v.get(i).x;
260                         ytab[i] = v.get(i).y;
261                 }
262                 fillPolygon(xtab,ytab, color);
263         }
264
265         
266         public void fillPolygon(double[] xtab, double[] ytab, 
267                         Color color) {
268                 if (xtab.length == ytab.length) {
269                         Point2D.Double points[] = new Point2D.Double[xtab.length];
270                         for (int i = 0; i < xtab.length; i++) {
271                                 points[i] = new Point2D.Double(xtab[i], ytab[i]);
272                                 updateBoundingBox(xtab[i], ytab[i]);
273                         }
274                         _commands.add(new FillPolygonCommand(points, color));
275                 }
276         }
277
278         public void setFont(int font, double size) {
279                 _fontsize = size;
280                 _font = font;
281                 _commands.add(new FontCommand(font, size));
282         }
283
284         public void setScale(double sc) {
285                 _scale = sc;
286         }
287
288         public double getScale() {
289                 return _scale;
290         }
291
292         public Rectangle2D.Double getBoundingBox() {
293                 return (new Rectangle2D.Double(_xmin, _ymin, _xmax - _xmin, _ymax
294                                 - _ymin));
295         }
296
297         private Point2D.Double transform(Point2D.Double p, double factor,
298                         double dx, double dy) {
299                 return transform(p.x, p.y, factor, dx, dy);
300         }
301
302         private Point2D.Double transform(double x, double y, double factor,
303                         double dx, double dy) {
304
305                 return new Point2D.Double((x + dx) * factor, (y + dy) * factor);
306         }
307
308         public String export() {
309                 Rectangle2D.Double oldbb = getBoundingBox();
310                 double dx = -oldbb.x;
311                 double dy = -oldbb.y;
312                 Rectangle2D.Double nbb = new Rectangle2D.Double(0, 0, oldbb.width* _scale, oldbb.height * _scale);
313                 StringBuffer buf = new StringBuffer();
314                 buf.append(headerS(nbb));
315                 if (_backgroundColor!= null)
316                 {
317                         double w = oldbb.width* _scale;
318                         double h = oldbb.height* _scale;
319                         Point2D.Double[] tab = new      Point2D.Double[4];
320                         tab[0] = new Point2D.Double(0,0);
321                         tab[1] = new Point2D.Double(w,0);
322                         tab[2] = new Point2D.Double(w,h);
323                         tab[3] = new Point2D.Double(0,h);
324                     buf.append(this.fillPolygonS(tab, _backgroundColor));
325                 }
326                 for (int i = 0; i < _commands.size(); i++) {
327                         GraphicElement ge = _commands.elementAt(i);
328                         if (ge instanceof LineCommand) {
329                                 LineCommand c = (LineCommand) ge;
330                                 String tmp = drawLineS(transform(c.get_orig(), _scale, dx, dy),
331                                                 transform(c.get_dest(), _scale, dx, dy), c
332                                                                 .get_thickness());
333                                 buf.append(tmp);
334                         } else if (ge instanceof TextCommand) {
335                                 TextCommand c = (TextCommand) ge;
336                                 String tmp = drawTextS(transform(c.get_base(), _scale, dx, dy),
337                                                 c.get_txt());
338                                 buf.append(tmp);
339                         } else if (ge instanceof RectangleCommand) {
340                                 RectangleCommand c = (RectangleCommand) ge;
341                                 String tmp = drawRectangleS(transform(c.get_orig(), _scale, dx,
342                                                 dy), transform(c.get_dims(), _scale, 0.0, 0.0), c
343                                                 .get_thickness());
344                                 buf.append(tmp);
345                         } else if (ge instanceof CircleCommand) {
346                                 CircleCommand c = (CircleCommand) ge;
347                                 String tmp = drawCircleS(
348                                                 transform(c.get_base(), _scale, dx, dy), c.get_radius()
349                                                                 * _scale, c.get_thickness());
350                                 buf.append(tmp);
351                         } else if (ge instanceof FillCircleCommand) {
352                                 FillCircleCommand c = (FillCircleCommand) ge;
353                                 String tmp = fillCircleS(
354                                                 transform(c.get_base(), _scale, dx, dy), c.get_radius()
355                                                                 * _scale, c.get_thickness(), c.get_color());
356                                 buf.append(tmp);
357                         } else if (ge instanceof FontCommand) {
358                                 FontCommand c = (FontCommand) ge;
359                                 String tmp = setFontS(c.get_font(), c.get_size());
360                                 buf.append(tmp);
361                         } else if (ge instanceof ColorCommand) {
362                                 ColorCommand c = (ColorCommand) ge;
363                                 String tmp = setColorS(c.getColor());
364                                 buf.append(tmp);
365                         } else if (ge instanceof ArcCommand) {                          
366                                 ArcCommand c = (ArcCommand) ge;
367                                 String tmp = drawArcS(
368                                                 transform(c.getCenter(), _scale, dx, dy), c.getWidth()
369                                                                 * _scale, c.getHeight() * _scale, c
370                                                                 .getStartAngle(), c.getEndAngle());
371                                 buf.append(tmp);
372                         } else if (ge instanceof PolygonCommand) {
373                                 PolygonCommand c = (PolygonCommand) ge;
374                                 Point2D.Double[] points = c.get_points();
375                                 for (int j = 0; j < points.length; j++) {
376                                         points[j] = transform(points[j], _scale, dx, dy);
377                                 }
378                                 String tmp = drawPolygonS(points, c.get_thickness());
379                                 buf.append(tmp);
380                         } else if (ge instanceof FillPolygonCommand) {
381                                 FillPolygonCommand c = (FillPolygonCommand) ge;
382                                 Point2D.Double[] points = c.get_points();
383                                 for (int j = 0; j < points.length; j++) {
384                                         points[j] = transform(points[j], _scale, dx, dy);
385                                 }
386                                 String tmp = fillPolygonS(points, c
387                                                 .get_color());
388                                 buf.append(tmp);
389                         }
390                 }
391                 buf.append(footerS());
392                 return buf.toString();
393         }
394
395         public void reset() {
396
397         }
398         
399         
400 }