1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.edit.client.command.path;
19
20 import org.vectomatic.dom.svg.OMSVGCircleElement;
21 import org.vectomatic.dom.svg.OMSVGDocument;
22 import org.vectomatic.dom.svg.OMSVGLineElement;
23 import org.vectomatic.dom.svg.OMSVGMatrix;
24 import org.vectomatic.dom.svg.OMSVGPathSeg;
25 import org.vectomatic.dom.svg.OMSVGPathSegCurvetoQuadraticAbs;
26 import org.vectomatic.dom.svg.OMSVGPoint;
27 import org.vectomatic.svg.edit.client.command.path.IPathRepOwner.Mode;
28
29 import com.google.gwt.dom.client.Element;
30
31
32
33
34
35 public class SVGQuadraticSegRep extends SVGSegRep {
36 protected OMSVGPathSegCurvetoQuadraticAbs quadraticToSeg;
37 protected OMSVGCircleElement cp;
38 protected OMSVGLineElement tg1;
39 protected OMSVGLineElement tg2;
40
41 public SVGQuadraticSegRep(IPathRepOwner owner, OMSVGPathSegCurvetoQuadraticAbs quadraticToSeg) {
42 super(owner);
43 this.quadraticToSeg = quadraticToSeg;
44
45
46 OMSVGDocument document = (OMSVGDocument) owner.getSvg().getOwnerDocument();
47 cp = document.createSVGCircleElement();
48 tg1 = document.createSVGLineElement();
49 tg2 = document.createSVGLineElement();
50 tangents.appendChild(tg1);
51 tangents.appendChild(tg2);
52 tangents.appendChild(cp);
53 }
54
55 @Override
56 public OMSVGPathSeg getElement() {
57 return quadraticToSeg;
58 }
59
60 @Override
61 public float getX() {
62 return quadraticToSeg.getX();
63 }
64 @Override
65 public void setX(float x) {
66 quadraticToSeg.setX(x);
67 }
68 @Override
69 public float getY() {
70 return quadraticToSeg.getY();
71 }
72 @Override
73 public void setY(float y) {
74 quadraticToSeg.setY(y);
75 }
76 @Override
77 public float getX1() {
78 return quadraticToSeg.getX1();
79 }
80 @Override
81 public float getY1() {
82 return quadraticToSeg.getY1();
83 }
84 @Override
85 public float getX2() {
86 return getX1();
87 }
88 @Override
89 public float getY2() {
90 return getY1();
91 }
92 @Override
93 public Element getCp1() {
94 return cp.getElement();
95 }
96 @Override
97 public void setCp1(OMSVGPoint p, float hs) {
98 quadraticToSeg.setX1(p.getX());
99 quadraticToSeg.setY1(p.getY());
100 update(hs);
101 }
102 @Override
103 public Element getCp2() {
104 return getCp1();
105 }
106 @Override
107 public void setCp2(OMSVGPoint p, float hs) {
108 setCp1(p, hs);
109 }
110
111 @Override
112 public void update(float hs) {
113 float x = quadraticToSeg.getX();
114 float y = quadraticToSeg.getY();
115 vertex.getX().getBaseVal().setValue(x - hs);
116 vertex.getY().getBaseVal().setValue(y - hs);
117 vertex.getWidth().getBaseVal().setValue(hs * 2);
118 vertex.getHeight().getBaseVal().setValue(hs * 2);
119 if (owner.getMode() == Mode.TANGENT) {
120 float px = previous != null ? previous.getX() : 0;
121 float py = previous != null ? previous.getY() : 0;
122 float x1 = quadraticToSeg.getX1();
123 float y1 = quadraticToSeg.getY1();
124
125 tg1.getX1().getBaseVal().setValue(px);
126 tg1.getY1().getBaseVal().setValue(py);
127 tg1.getX2().getBaseVal().setValue(x1);
128 tg1.getY2().getBaseVal().setValue(y1);
129
130 tg2.getX1().getBaseVal().setValue(x);
131 tg2.getY1().getBaseVal().setValue(y);
132 tg2.getX2().getBaseVal().setValue(x1);
133 tg2.getY2().getBaseVal().setValue(y1);
134
135 cp.getCx().getBaseVal().setValue(x1);
136 cp.getCy().getBaseVal().setValue(y1);
137 cp.getR().getBaseVal().setValue(hs);
138 }
139 }
140
141 @Override
142 public void updateStart(OMSVGPoint delta, float hs) {
143 quadraticToSeg.setX1(quadraticToSeg.getX1() + delta.getX());
144 quadraticToSeg.setY1(quadraticToSeg.getY1() + delta.getY());
145 update(hs);
146 }
147
148 @Override
149 public void updateEnd(OMSVGPoint delta, float hs) {
150 quadraticToSeg.setX(quadraticToSeg.getX() + delta.getX());
151 quadraticToSeg.setY(quadraticToSeg.getY() + delta.getY());
152 quadraticToSeg.setX1(quadraticToSeg.getX1() + delta.getX());
153 quadraticToSeg.setY1(quadraticToSeg.getY1() + delta.getY());
154 update(hs);
155 }
156
157 @Override
158 public void processMouseMove(OMSVGPoint delta, Element target, float hs, boolean isCtrlKeyDown) {
159 if (target == null) {
160 updateEnd(delta, hs);
161 if (next != null) {
162 next.updateStart(delta, hs);
163 }
164 } else if (tg2.getElement() == target) {
165 updateEnd(delta, hs);
166 if (next != null) {
167 next.updateStart(delta, hs);
168 }
169 } else if (tg1.getElement() == target) {
170 updateStart(delta, hs);
171 if (previous != null) {
172 previous.updateEnd(delta, hs);
173 }
174 } else if (cp.getElement() == target) {
175 SVGSegRep prevSeg = getPreviousSplineSeg();
176 SVGSegRep nextSeg = getNextSplineSeg();
177 Float anglePrev = null;
178 Float angleNext = null;
179 if (isCtrlKeyDown) {
180 if (prevSeg != null) {
181
182 OMSVGPoint v1 = owner.getSvg().createSVGPoint(
183 quadraticToSeg.getX1() - prevSeg.getX(),
184 quadraticToSeg.getY1() - prevSeg.getY());
185 OMSVGPoint v2 = owner.getSvg().createSVGPoint(
186 quadraticToSeg.getX1() + delta.getX() - prevSeg.getX(),
187 quadraticToSeg.getY1() + delta.getY() - prevSeg.getY());
188 float d = v1.length() * v2.length();
189 if (d != 0) {
190 anglePrev = (float)(Math.acos(v1.dotProduct(v2) / d) * 180 / Math.PI);
191 if (v1.crossProduct(v2) < 0) {
192 anglePrev = 360 - anglePrev;
193 }
194 }
195 }
196 if (nextSeg != null) {
197
198 OMSVGPoint v1 = owner.getSvg().createSVGPoint(
199 quadraticToSeg.getX1() - quadraticToSeg.getX(),
200 quadraticToSeg.getY1() - quadraticToSeg.getY());
201 OMSVGPoint v2 = owner.getSvg().createSVGPoint(
202 quadraticToSeg.getX1() + delta.getX() - quadraticToSeg.getX(),
203 quadraticToSeg.getY1() + delta.getY() - quadraticToSeg.getY());
204 float d = v1.length() * v2.length();
205 if (d != 0) {
206 angleNext = (float)(Math.acos(v1.dotProduct(v2) / d) * 180 / Math.PI);
207 if (v1.crossProduct(v2) < 0) {
208 angleNext = 360 - angleNext;
209 }
210 }
211 }
212 }
213 quadraticToSeg.setX1(quadraticToSeg.getX1() + delta.getX());
214 quadraticToSeg.setY1(quadraticToSeg.getY1() + delta.getY());
215 update(hs);
216 if (anglePrev != null) {
217
218 OMSVGMatrix m = owner.getSvg().createSVGMatrix();
219 m = m.translate(prevSeg.getX(), prevSeg.getY());
220 m = m.rotate(anglePrev);
221 m = m.translate(-prevSeg.getX(), -prevSeg.getY());
222 OMSVGPoint p0 = owner.getSvg().createSVGPoint(
223 prevSeg.getX2(),
224 prevSeg.getY2());
225 OMSVGPoint p1 = p0.matrixTransform(m).substract(p0);
226 prevSeg.processMouseMove(p1, prevSeg.getCp2(), hs, false);
227 }
228 if (angleNext != null) {
229
230 OMSVGMatrix m = owner.getSvg().createSVGMatrix();
231 m = m.translate(quadraticToSeg.getX(), quadraticToSeg.getY());
232 m = m.rotate(angleNext);
233 m = m.translate(-quadraticToSeg.getX(), -quadraticToSeg.getY());
234 OMSVGPoint p0 = owner.getSvg().createSVGPoint(
235 nextSeg.getX1(),
236 nextSeg.getY1());
237 OMSVGPoint p1 = p0.matrixTransform(m).substract(p0);
238 nextSeg.processMouseMove(p1, nextSeg.getCp1(), hs, false);
239 }
240 }
241 }
242
243 @Override
244 public String toString() {
245 StringBuilder builder = new StringBuilder("Q ");
246 builder.append(quadraticToSeg.getX1());
247 builder.append(",");
248 builder.append(quadraticToSeg.getY1());
249 builder.append(" ");
250 builder.append(quadraticToSeg.getX());
251 builder.append(",");
252 builder.append(quadraticToSeg.getY());
253 return builder.toString();
254 }
255
256 }