1 /**********************************************
2 * Copyright (C) 2010 Lukas Laag
3 * This file is part of lib-gwt-svg.
4 *
5 * libgwtsvg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * libgwtsvg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with libgwtsvg. If not, see http://www.gnu.org/licenses/
17 **********************************************/
18 /*
19 * Copyright (c) 2004 World Wide Web Consortium,
20 *
21 * (Massachusetts Institute of Technology, European Research Consortium for
22 * Informatics and Mathematics, Keio University). All Rights Reserved. This
23 * work is distributed under the W3C(r) Software License [1] in the hope that
24 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
25 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 *
27 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
28 */
29
30 package org.vectomatic.dom.svg.impl;
31
32 import org.vectomatic.dom.svg.OMSVGAnimatedBoolean;
33 import org.vectomatic.dom.svg.OMSVGAnimatedLength;
34 import org.vectomatic.dom.svg.OMSVGAnimatedTransformList;
35 import org.vectomatic.dom.svg.OMSVGMatrix;
36 import org.vectomatic.dom.svg.OMSVGPoint;
37 import org.vectomatic.dom.svg.OMSVGRect;
38 import org.vectomatic.dom.svg.OMSVGStringList;
39
40 import com.google.gwt.core.client.JavaScriptException;
41
42 /**
43 * The {@link org.vectomatic.dom.svg.impl.SVGLineElement} interface corresponds
44 * to the <a href='http://www.w3.org/TR/SVG11/shapes.html#LineElement' title='line
45 * element specification'>line</a> element.
46 */
47 public class SVGLineElement extends SVGElement {
48 protected SVGLineElement() {
49 }
50
51 // Implementation of the svg::SVGLineElement W3C IDL interface
52 /**
53 * Corresponds to attribute {@link org.vectomatic.dom.svg.impl.SVGLineElement#getX1()}
54 * on the given <a href='http://www.w3.org/TR/SVG11/shapes.html#LineElement'
55 * title='line element specification'>line</a> element.
56 */
57 public final native OMSVGAnimatedLength getX1() /*-{
58 return this.x1;
59 }-*/;
60 /**
61 * Corresponds to attribute {@link org.vectomatic.dom.svg.impl.SVGLineElement#getY1()}
62 * on the given <a href='http://www.w3.org/TR/SVG11/shapes.html#LineElement'
63 * title='line element specification'>line</a> element.
64 */
65 public final native OMSVGAnimatedLength getY1() /*-{
66 return this.y1;
67 }-*/;
68 /**
69 * Corresponds to attribute {@link org.vectomatic.dom.svg.impl.SVGLineElement#getX2()}
70 * on the given <a href='http://www.w3.org/TR/SVG11/shapes.html#LineElement'
71 * title='line element specification'>line</a> element.
72 */
73 public final native OMSVGAnimatedLength getX2() /*-{
74 return this.x2;
75 }-*/;
76 /**
77 * Corresponds to attribute {@link org.vectomatic.dom.svg.impl.SVGLineElement#getY2()}
78 * on the given <a href='http://www.w3.org/TR/SVG11/shapes.html#LineElement'
79 * title='line element specification'>line</a> element.
80 */
81 public final native OMSVGAnimatedLength getY2() /*-{
82 return this.y2;
83 }-*/;
84
85 // Implementation of the svg::SVGExternalResourcesRequired W3C IDL interface
86 /**
87 * Corresponds to attribute {@link org.vectomatic.dom.svg.itf.ISVGExternalResourcesRequired#getExternalResourcesRequired()}
88 * on the given element. Note that the SVG DOM defines the attribute {@link
89 * org.vectomatic.dom.svg.itf.ISVGExternalResourcesRequired#getExternalResourcesRequired()}
90 * as being of type {@link org.vectomatic.dom.svg.OMSVGAnimatedBoolean}, whereas
91 * the SVG language definition says that {@link org.vectomatic.dom.svg.itf.ISVGExternalResourcesRequired#getExternalResourcesRequired()}
92 * is not animated. Because the SVG language definition states that {@link
93 * org.vectomatic.dom.svg.itf.ISVGExternalResourcesRequired#getExternalResourcesRequired()}
94 * cannot be animated, the {@link org.vectomatic.dom.svg.OMSVGAnimatedBoolean#getAnimVal()}
95 * will always be the same as the {@link org.vectomatic.dom.svg.OMSVGAnimatedBoolean#getBaseVal()}.
96 */
97 public final native OMSVGAnimatedBoolean getExternalResourcesRequired() /*-{
98 return this.externalResourcesRequired;
99 }-*/;
100
101 // Implementation of the svg::SVGLangSpace W3C IDL interface
102 /**
103 * Corresponds to attribute <code>xml:lang</code> on the given element.
104 */
105 public final native String getXmllang() /*-{
106 return this.xmllang;
107 }-*/;
108 /**
109 * Corresponds to attribute <code>xml:lang</code> on the given element.
110 * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised on an attempt
111 * to change the value of a <a href="svgdom.html#ReadOnlyNodes">read only
112 * attribute</a>.
113 */
114 public final native void setXmllang(String value) throws JavaScriptException /*-{
115 this.xmllang = value;
116 }-*/;
117 /**
118 * Corresponds to attribute <code>xml:space</code> on the given element.
119 */
120 public final native String getXmlspace() /*-{
121 return this.xmlspace;
122 }-*/;
123 /**
124 * Corresponds to attribute <code>xml:space</code> on the given element.
125 * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised on an attempt
126 * to change the value of a <a href="svgdom.html#ReadOnlyNodes">read only
127 * attribute</a>.
128 */
129 public final native void setXmlspace(String value) throws JavaScriptException /*-{
130 this.xmlspace = value;
131 }-*/;
132
133 // Implementation of the svg::SVGLocatable W3C IDL interface
134 /**
135 * The element which established the current viewport. Often, the nearest
136 * ancestor <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' title='svg
137 * element specification'>svg</a> element. Null if the current element is
138 * the outermost <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement'
139 * title='svg element specification'>svg</a> element.
140 */
141 public final native SVGElement getNearestViewportElement() /*-{
142 return this.nearestViewportElement;
143 }-*/;
144 /**
145 * The farthest ancestor <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement'
146 * title='svg element specification'>svg</a> element. Null if the current
147 * element is the outermost <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement'
148 * title='svg element specification'>svg</a> element.
149 */
150 public final native SVGElement getFarthestViewportElement() /*-{
151 return this.farthestViewportElement;
152 }-*/;
153 /**
154 * Returns the tight bounding box in current user space (i.e., after application
155 * of the <code>transform</code> attribute, if any) on the geometry of all
156 * contained graphics elements, exclusive of stroking, clipping, masking and
157 * filter effects). Note that getBBox must return the actual bounding box
158 * at the time the method was called, even in case the element has not yet
159 * been rendered.
160 * @return An {@link org.vectomatic.dom.svg.OMSVGRect} object that defines
161 * the bounding box.
162 */
163 public final native OMSVGRect getBBox() /*-{
164 return this.getBBox();
165 }-*/;
166 /**
167 * Returns the transformation matrix from current user units (i.e., after
168 * application of the <code>transform</code> attribute, if any) to the viewport
169 * coordinate system for the {@link org.vectomatic.dom.svg.itf.ISVGLocatable#getNearestViewportElement()}.
170 * @return An {@link org.vectomatic.dom.svg.OMSVGMatrix} object that defines
171 * the CTM.
172 */
173 public final native OMSVGMatrix getCTM() /*-{
174 return this.getCTM();
175 }-*/;
176 /**
177 * Returns the transformation matrix from current user units (i.e., after
178 * application of the <code>transform</code> attribute, if any) to the parent
179 * user agent's notice of a "pixel". For display devices, ideally this represents
180 * a physical screen pixel. For other devices or environments where physical
181 * pixel sizes are not known, then an algorithm similar to the CSS2 definition
182 * of a "pixel" can be used instead. Note that null is returned if this element
183 * is not hooked into the document tree. This method would have been more
184 * aptly named as <code>getClientCTM</code>, but the name <code>getScreenCTM</code>
185 * is kept for historical reasons.
186 * @return An {@link org.vectomatic.dom.svg.OMSVGMatrix} object that defines
187 * the given transformation matrix.
188 */
189 public final native OMSVGMatrix getScreenCTM() /*-{
190 return this.getScreenCTM();
191 }-*/;
192 /**
193 * Returns the transformation matrix from the user coordinate system on the
194 * current element (after application of the <code>transform</code> attribute,
195 * if any) to the user coordinate system on parameter <var>element</var> (after
196 * application of its <code>transform</code> attribute, if any).
197 * @param element The target element.
198 * @return An {@link org.vectomatic.dom.svg.OMSVGMatrix} object that defines
199 * the transformation.
200 * @throws SVGException(SVG_MATRIX_NOT_INVERTABLE) Raised if the currently
201 * defined transformation matrices make it impossible to compute the given
202 * matrix (e.g., because one of the transformations is singular).
203 */
204 public final native OMSVGMatrix getTransformToElement(SVGElement element) throws JavaScriptException /*-{
205 return this.getTransformToElement(element);
206 }-*/;
207
208 // Implementation of the svg::SVGTests W3C IDL interface
209 /**
210 * Corresponds to attribute {@link org.vectomatic.dom.svg.itf.ISVGTests#getRequiredFeatures()}
211 * on the given element.
212 */
213 public final native OMSVGStringList getRequiredFeatures() /*-{
214 return @org.vectomatic.dom.svg.OMNode::convertList(Lcom/google/gwt/core/client/JavaScriptObject;)(this.requiredFeatures);
215 }-*/;
216 /**
217 * Corresponds to attribute {@link org.vectomatic.dom.svg.itf.ISVGTests#getRequiredExtensions()}
218 * on the given element.
219 */
220 public final native OMSVGStringList getRequiredExtensions() /*-{
221 return @org.vectomatic.dom.svg.OMNode::convertList(Lcom/google/gwt/core/client/JavaScriptObject;)(this.requiredExtensions);
222 }-*/;
223 /**
224 * Corresponds to attribute {@link org.vectomatic.dom.svg.itf.ISVGTests#getSystemLanguage()}
225 * on the given element.
226 */
227 public final native OMSVGStringList getSystemLanguage() /*-{
228 return @org.vectomatic.dom.svg.OMNode::convertList(Lcom/google/gwt/core/client/JavaScriptObject;)(this.systemLanguage);
229 }-*/;
230 /**
231 * Returns true if the user agent supports the given extension, specified
232 * by a URI.
233 * @param extension The name of the extension, expressed as a URI.
234 * @return True or false, depending on whether the given extension is supported.
235 */
236 public final native boolean hasExtension(String extension) /*-{
237 return this.hasExtension(extension);
238 }-*/;
239
240 // Implementation of the svg::SVGTransformable W3C IDL interface
241 /**
242 * Corresponds to attribute {@link org.vectomatic.dom.svg.itf.ISVGTransformable#getTransform()}
243 * on the given element.
244 */
245 public final native OMSVGAnimatedTransformList getTransform() /*-{
246 return this.transform;
247 }-*/;
248
249 // Helper methods
250 /**
251 * Computes the intersection point between this line and the tangent
252 * perpendicular to this line through p. The intersection is
253 * returned in parametric form. If one considers the parametric
254 * equation of this line to be:
255 * <pre>P = P1 + t * (P2 - P1)</pre>
256 * then this method returns the value of t at the intersection point.
257 * @param p The point which defines the tangent.
258 * @return the parametric value of the intersection point.
259 */
260 public final native float parametricIntersection(OMSVGPoint p) /*-{
261 var x1 = this.x1.baseVal.value;
262 var y1 = this.y1.baseVal.value;
263 var x2 = this.x2.baseVal.value;
264 var y2 = this.y2.baseVal.value;
265 var dx = x2 - x1;
266 var dy = y2 - y1;
267 return ((p.x - x1)*(x2 - x1) + (p.y - y1)*(y2 - y1))/(dx * dx + dy * dy);
268 }-*/;
269 /**
270 * Computes the intersection point between this line and the tangent
271 * perpendicular to this line through p.
272 * @param p The point which defines the tangent.
273 * @return the intersection point.
274 */
275 public final OMSVGPoint intersectionPoint(OMSVGPoint p) {
276 OMSVGPoint destination = getOwnerSVGElement().createSVGPoint();
277 return intersectionPoint(p,destination);
278 }
279 /**
280 * Computes the intersection point between this line and the tangent
281 * perpendicular to this line through p and puts the
282 * result in the specified destination point.
283 * @param p The point which defines the tangent.
284 * @param destination The point where to store the result.
285 * @return the intersection point.
286 */
287 public final OMSVGPoint intersectionPoint(OMSVGPoint p, OMSVGPoint destination) {
288 float u = parametricIntersection(p);
289 float x1 = getX1().getBaseVal().getValue();
290 float y1 = getY1().getBaseVal().getValue();
291 float x2 = getX2().getBaseVal().getValue();
292 float y2 = getY2().getBaseVal().getValue();
293 float dx = x2 - x1;
294 float dy = y2 - y1;
295 destination.setX(x1 + u * dx);
296 destination.setY(y1 + u * dy);
297 return destination;
298 }
299 /**
300 * Computes the distance from the specified point to this line.
301 * @param p A point in the plane
302 * @return the distance to this line.
303 */
304 public final float distanceToLine(OMSVGPoint p) {
305 return p.distance(intersectionPoint(p));
306 }
307 }