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
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.
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.
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.
18 package fr.orsay.lri.varna.models.export;
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;
28 import fr.orsay.lri.varna.models.rna.ModeleBP;
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;
44 private Vector<GraphicElement> _commands = new Vector<GraphicElement>();
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;
52 protected Color _curColor = Color.black;
53 protected Color _backgroundColor = null;
55 protected double _fontsize = 10.0;
56 protected int _font = FONT_HELVETICA_BOLD;
59 public Color getCurrentColor() {
63 public double getCurFontSize() {
67 public int getCurrentFont() {
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);
79 public abstract String drawLineS(Point2D.Double orig,
80 Point2D.Double dest, double thickness);
83 public abstract String drawArcS(Point2D.Double origine, double width,
84 double height, double startAngle, double endAngle);
86 public abstract String drawTextS(Point2D.Double base, String txt);
88 public abstract String drawRectangleS(Point2D.Double orig,
89 Point2D.Double dims, double thickness);
91 public abstract String drawCircleS(Point2D.Double base, double radius,
94 public abstract String fillCircleS(Point2D.Double base, double radius,
95 double thickness, Color color);
97 public abstract String drawPolygonS(Point2D.Double[] points,
100 public abstract String fillPolygonS(Point2D.Double[] points,
103 public abstract String setFontS(int font, double size);
105 public String setColorS(Color col) {
110 public abstract String headerS(Rectangle2D.Double bb);
112 public abstract String footerS();
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;
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);
129 public void drawLine(double x0, double y0, double x1, double y1,
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));
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,
145 public void drawText(double x, double y, String txt) {
146 updateBoundingBox(x, y);
148 _commands.add(new TextCommand(new Point2D.Double(x, y), new String(txt)));
151 public void drawRectangle(double x, double y, double w, double h,
153 updateBoundingBox(x, y);
154 updateBoundingBox(x + w, y + h);
156 _commands.add(new RectangleCommand(new Point2D.Double(x, y),
157 new Point2D.Double(w, h), thickness));
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];
171 fillPolygon(xtab, ytab, color);
174 public void drawCircle(double x, double y, double radius, double thickness) {
175 updateBoundingBox(x - radius, y - radius);
176 updateBoundingBox(x + radius, y + radius);
178 _commands.add(new CircleCommand(new Point2D.Double(x, y), radius,
183 public void setColor(Color col) {
185 _commands.add(new ColorCommand(col));
188 public void setBackgroundColor(Color col){
189 _backgroundColor = col;
192 public void removeBackgroundColor(){
193 _backgroundColor = null;
196 public void fillCircle(double x, double y, double radius, double thickness,
198 updateBoundingBox(x - radius, y - radius);
199 updateBoundingBox(x + radius, y + radius);
201 _commands.add(new FillCircleCommand(new Point2D.Double(x, y), radius,
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]);
212 _commands.add(new PolygonCommand(points, thickness));
216 public void drawPolygon(GeneralPath p,
218 PathIterator pi = p.getPathIterator(null);
219 Vector<Point2D.Double> v = new Vector<Point2D.Double>();
220 double[] coords = new double[6];
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])); }
230 double[] xtab = new double[v.size()];
231 double[] ytab = new double[v.size()];
232 for(int i=0;i<v.size();i++)
234 xtab[i] = v.get(i).x;
235 ytab[i] = v.get(i).y;
237 drawPolygon(xtab,ytab, thickness);
241 public void fillPolygon(GeneralPath p,
243 PathIterator pi = p.getPathIterator(null);
244 Vector<Point2D.Double> v = new Vector<Point2D.Double>();
245 double[] coords = new double[6];
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])); }
255 double[] xtab = new double[v.size()];
256 double[] ytab = new double[v.size()];
257 for(int i=0;i<v.size();i++)
259 xtab[i] = v.get(i).x;
260 ytab[i] = v.get(i).y;
262 fillPolygon(xtab,ytab, color);
266 public void fillPolygon(double[] xtab, double[] ytab,
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]);
274 _commands.add(new FillPolygonCommand(points, color));
278 public void setFont(int font, double size) {
281 _commands.add(new FontCommand(font, size));
284 public void setScale(double sc) {
288 public double getScale() {
292 public Rectangle2D.Double getBoundingBox() {
293 return (new Rectangle2D.Double(_xmin, _ymin, _xmax - _xmin, _ymax
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);
302 private Point2D.Double transform(double x, double y, double factor,
303 double dx, double dy) {
305 return new Point2D.Double((x + dx) * factor, (y + dy) * factor);
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)
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));
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
334 } else if (ge instanceof TextCommand) {
335 TextCommand c = (TextCommand) ge;
336 String tmp = drawTextS(transform(c.get_base(), _scale, dx, dy),
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
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());
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());
357 } else if (ge instanceof FontCommand) {
358 FontCommand c = (FontCommand) ge;
359 String tmp = setFontS(c.get_font(), c.get_size());
361 } else if (ge instanceof ColorCommand) {
362 ColorCommand c = (ColorCommand) ge;
363 String tmp = setColorS(c.getColor());
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());
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);
378 String tmp = drawPolygonS(points, c.get_thickness());
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);
386 String tmp = fillPolygonS(points, c
391 buf.append(footerS());
392 return buf.toString();
395 public void reset() {