1 package com.jgraph.io.svg;
2 
3 import java.awt.Point;
4 import java.awt.geom.Point2D;
5 import java.awt.geom.Rectangle2D;
6 
7 import org.jgraph.graph.CellView;
8 import org.jgraph.graph.VertexRenderer;
9 import org.jgraph.graph.VertexView;
10 
11 public class SVGVertexRenderer extends VertexRenderer {
12 
13 		/**
14 		 * Holds the shape of the current view.
15 		 */
16 		protected int shape = 0;
17 
getPerimeterPoint(VertexView view, Point2D source, Point2D p)18 		public Point2D getPerimeterPoint(VertexView view, Point2D source,
19 				Point2D p) {
20 			int shape = SVGGraphConstants
21 					.getShape(view.getAllAttributes());
22 			if (shape == SVGGraphConstants.SHAPE_ELLIPSE) {
23 				return getEllipsePerimeterPoint(view, source, p);
24 			}
25 			return super.getPerimeterPoint(view, source, p);
26 		}
27 
installAttributes(CellView view)28 		public void installAttributes(CellView view) {
29 			super.installAttributes(view);
30 //			Map map = view.getAllAttributes();
31 			shape = SVGGraphConstants.getShape(view.getAllAttributes());
32 		}
33 
34 		/**
35 		 * Utility method to return the perimeter point for a circle.
36 		 *
37 		 * @param view
38 		 *            The view that defines the bounds of the circle.
39 		 * @param source
40 		 *            The start point of theline to intersect with the circle.
41 		 * @param p
42 		 *            The end point of the line to intersect with the circle.
43 		 * @return The interaction of the circle and the line between source and
44 		 *         p.
45 		 */
getEllipsePerimeterPoint(VertexView view, Point2D source, Point2D p)46 		public Point2D getEllipsePerimeterPoint(VertexView view,
47 				Point2D source, Point2D p) {
48 			Rectangle2D r = view.getBounds();
49 
50 			double x = r.getX();
51 			double y = r.getY();
52 			double a = (r.getWidth() + 1) / 2;
53 			double b = (r.getHeight() + 1) / 2;
54 
55 			// x0,y0 - center of ellipse
56 			double x0 = x + a;
57 			double y0 = y + b;
58 
59 			// x1, y1 - point
60 			double x1 = p.getX();
61 			double y1 = p.getY();
62 
63 			// Calculates straight line equation through point and ellipse
64 			// center
65 			// y = d * x + h
66 			double dx = x1 - x0;
67 			double dy = y1 - y0;
68 
69 			if (dx == 0)
70 				return new Point((int) x0, (int) (y0 + b * dy / Math.abs(dy)));
71 
72 			double d = dy / dx;
73 			double h = y0 - d * x0;
74 
75 			// Calculates intersection
76 			double e = a * a * d * d + b * b;
77 			double f = -2 * x0 * e;
78 			double g = a * a * d * d * x0 * x0 + b * b * x0 * x0 - a * a * b
79 					* b;
80 
81 			double det = Math.sqrt(f * f - 4 * e * g);
82 
83 			// Two solutions (perimeter points)
84 			double xout1 = (-f + det) / (2 * e);
85 			double xout2 = (-f - det) / (2 * e);
86 			double yout1 = d * xout1 + h;
87 			double yout2 = d * xout2 + h;
88 
89 			double dist1 = Math.sqrt(Math.pow((xout1 - x1), 2)
90 					+ Math.pow((yout1 - y1), 2));
91 			double dist2 = Math.sqrt(Math.pow((xout2 - x1), 2)
92 					+ Math.pow((yout2 - y1), 2));
93 
94 			// Correct solution
95 			double xout, yout;
96 
97 			if (dist1 < dist2) {
98 				xout = xout1;
99 				yout = yout1;
100 			} else {
101 				xout = xout2;
102 				yout = yout2;
103 			}
104 
105 			return new Point2D.Double(xout, yout);
106 		}
107 
108 	}