View Javadoc

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;
31  
32  import com.google.gwt.core.client.JavaScriptException;
33  import com.google.gwt.core.client.JavaScriptObject;
34  
35  /**
36   * <p>Represents rectangular geometry.  Rectangles are defined as consisting
37   * of a (x,y) coordinate pair identifying a minimum X value, a minimum Y value,
38   * and a width and height, which are usually constrained to be non-negative.</p>
39   * <p id="ReadOnlyRect">An {@link org.vectomatic.dom.svg.OMSVGRect} object
40   * can be designated as <em>read only</em>, which means that attempts to modify
41   * the object will result in an exception being thrown, as described below.</p>
42   */
43  public class OMSVGRect extends JavaScriptObject {
44    protected OMSVGRect() {
45    }
46  
47    // Implementation of the svg::SVGRect W3C IDL interface
48    /**
49     * The <var>x</var> coordinate of the rectangle, in user units.
50     */
51    public final native float getX() /*-{
52      return this.x;
53    }-*/;
54    /**
55     * The <var>x</var> coordinate of the rectangle, in user units.
56     * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised when the rectangle
57     * corresponds to a <a href="svgdom.html#ReadOnlyNodes">read only attribute</a>
58     * or when the object itself is   <a href="#ReadOnlyRect">read only</a>.
59     */
60    public final native void setX(float value) throws JavaScriptException /*-{
61      this.x = value;
62    }-*/;
63    /**
64     * The <var>y</var> coordinate of the rectangle, in user units.
65     */
66    public final native float getY() /*-{
67      return this.y;
68    }-*/;
69    /**
70     * The <var>y</var> coordinate of the rectangle, in user units.
71     * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised when the rectangle
72     * corresponds to a <a href="svgdom.html#ReadOnlyNodes">read only attribute</a>
73     * or when the object itself is   <a href="#ReadOnlyRect">read only</a>.
74     */
75    public final native void setY(float value) throws JavaScriptException /*-{
76      this.y = value;
77    }-*/;
78    /**
79     * The <var>width</var> coordinate of the rectangle, in user units.
80     */
81    public final native float getWidth() /*-{
82      return this.width;
83    }-*/;
84    /**
85     * The <var>width</var> coordinate of the rectangle, in user units.
86     * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised when the rectangle
87     * corresponds to a <a href="svgdom.html#ReadOnlyNodes">read only attribute</a>
88     * or when the object itself is   <a href="#ReadOnlyRect">read only</a>.
89     */
90    public final native void setWidth(float value) throws JavaScriptException /*-{
91      this.width = value;
92    }-*/;
93    /**
94     * The <var>height</var> coordinate of the rectangle, in user units.
95     */
96    public final native float getHeight() /*-{
97      return this.height;
98    }-*/;
99    /**
100    * The <var>height</var> coordinate of the rectangle, in user units.
101    * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised when the rectangle
102    * corresponds to a <a href="svgdom.html#ReadOnlyNodes">read only attribute</a>
103    * or when the object itself is   <a href="#ReadOnlyRect">read only</a>.
104    */
105   public final native void setHeight(float value) throws JavaScriptException /*-{
106     this.height = value;
107   }-*/;
108 
109   // Helper methods
110   /**
111    * Returns the X coordinate of the center of this rectangle.
112    * @return the X coordinate of the center of this rectangle.
113    */
114   public final float getCenterX() {
115 	return getX() + 0.5f * getWidth();
116   }
117   /**
118    * Returns the Y coordinate of the center of this rectangle.
119    * @return the Y coordinate of the center of this rectangle.
120    */
121   public final float getCenterY() {
122 	return getY() + 0.5f * getHeight();
123   }
124   /**
125    * Returns the X coordinate of the right corners of this rectangle.
126    * @return the X coordinate of the right corners of this rectangle.
127    */
128   public final float getMaxX() {
129 	return getX() + getWidth();
130   }
131   /**
132    * Returns the X coordinate of the bottom corners of this rectangle.
133    * @return the X coordinate of the bottom corners of this rectangle.
134    */
135   public final float getMaxY() {
136 	return getY() + getHeight();
137   }
138   /**
139    * Computes the intersection of this rectangle with the
140    * specified rectangle and puts the result in this rectangle.
141    * The method returns null if the two rectangles have no intersection.
142    * @param r the rectangle to intersect
143    * @return the rectangle resulting from the intersection of
144    * this rectangle with the specified rectangle or 
145    * null if the two rectangles have no intersection.
146    */
147   public final OMSVGRect intersection(OMSVGRect r) {
148 	  return intersection(r, this);
149   }
150   /**
151    * Computes the intersection of this rectangle with the
152    * specified rectangle and puts the result in the destination rectangle.
153    * The method returns null if the two rectangles have no intersection.
154    * @param r the rectangle to intersect
155    * @param destination a rectangle to store the intersection
156    * @return the rectangle resulting from the intersection of
157    * this rectangle with the specified rectangle or 
158    * null if the two rectangles have no intersection.
159    */
160   public final OMSVGRect intersection(OMSVGRect r, OMSVGRect destination) {
161 	if (getX() < r.getX() && r.getX() < getMaxX()) {
162 		if (getY() < r.getY() && r.getY() < getMaxY()) {
163 			destination.setWidth(getMaxX() - r.getX());
164 			destination.setX(r.getX());
165 			destination.setHeight(getMaxY() - r.getY());
166 			destination.setY(r.getY());
167 			return destination;
168 		} else if (r.getY() < getY() && getY() < r.getMaxY()) {
169 			destination.setWidth(getMaxX() - r.getX());
170 			destination.setX(r.getX());
171 			destination.setHeight(r.getMaxY() - getY());
172 			destination.setY(getY());
173 			return destination;
174 		}
175 	} else if (r.getX() < getX() && getX() < r.getMaxX()) {
176 		if (getY() < r.getY() && r.getY() < getMaxY()) {
177 			destination.setWidth(r.getMaxX() - getX());
178 			destination.setX(getX());
179 			destination.setHeight(getMaxY() - r.getY());
180 			destination.setY(r.getY());
181 			return destination;
182 		} else if (r.getY() < getY() && getY() < r.getMaxY()) {
183 			destination.setWidth(r.getMaxX() - getX());
184 			destination.setX(getX());
185 			destination.setHeight(r.getMaxY() - getY());
186 			destination.setY(getY());
187 			return destination;
188 		}
189 	}
190 	return null;
191   }
192   /**
193    * Computes the union of this rectangle with the
194    * specified rectangle and puts the result in this rectangle.
195    * @param r the rectangle with which to compute the union
196    * @return the rectangle resulting from the union of
197    * this rectangle with the specified rectangle.
198    */
199   public final OMSVGRect union(OMSVGRect r) {
200 	  return union(r, this);
201   }
202   /**
203    * Computes the union of this rectangle with the
204    * specified rectangle and puts the result in the destination rectangle.
205    * @param r the rectangle with which to compute the union
206    * @param destination a rectangle to store the union
207    * @return the rectangle resulting from the union of
208    * this rectangle with the specified rectangle.
209    */
210   public final OMSVGRect union(OMSVGRect r, OMSVGRect destination) {
211 	  float x = Math.min(getX(), r.getX());
212 	  float y = Math.min(getY(), r.getY());
213 	  destination.setWidth(Math.max(getMaxX(), r.getMaxX()) - x);
214 	  destination.setHeight(Math.max(getMaxY(), r.getMaxY()) - y);
215 	  destination.setX(x);
216 	  destination.setY(y);
217 	  return destination;
218   }
219   /**
220    * Returns true if the specified point is inside this rectangle,
221    * false otherwise.
222    * @param p The point to test
223    * @return true if the specified point is inside this rectangle,
224    * false otherwise.
225    */
226   public final boolean contains(OMSVGPoint p) {
227 	  return p.getX() >= getX() && p.getY() >= getY() && p.getX() <= getMaxX() && p.getY() <= getMaxY();
228   }
229   /**
230    * Copies this rectangle to the specified destination rectangle.
231    * @param destination the destination rectangle.
232    * @return the destination rectangle.
233    */
234   public final native OMSVGRect assignTo(OMSVGRect destination) /*-{
235 	  destination.x = this.x;
236 	  destination.y = this.y;
237 	  destination.width = this.width;
238 	  destination.height = this.height;
239 	  return destination;
240   }-*/;
241   /**
242    * Returns a textual description of the rectangle for debugging purposes.
243    * @return a textual description of the rectangle.
244    */
245   public final String getDescription() {
246 	  StringBuilder builder = new StringBuilder("{");
247 	  builder.append(getX());
248 	  builder.append(" ");
249 	  builder.append(getY());
250 	  builder.append(" ");
251 	  builder.append(getWidth());
252 	  builder.append(" ");
253 	  builder.append(getHeight());
254 	  builder.append("}");
255 	  return builder.toString();
256   } 
257   /**
258    * Modifies the position and size of this rectangle by adding
259    * the specified margin to it.
260    * @param x the horizontal margin
261    * @param y the vertical margin
262    * @return this rectangle
263    */
264   public final OMSVGRect inset(float x, float y) {
265 	  return inset(this, x, y);
266   }
267   /**
268    * Modifies the position and size of this rectangle by adding
269    * the specified margin to it and puts the result in the destination 
270    * rectangle.
271    * @param destination the destination rectangle.
272    * @param x the horizontal margin
273    * @param y the vertical margin
274    * @return the destination rectangle.
275    */
276   public final OMSVGRect inset(OMSVGRect destination, float x, float y) {
277 	  destination.setX(getX() + x);
278 	  destination.setY(getY() + y);
279 	  destination.setWidth(getWidth() - x * 2);
280 	  destination.setHeight(getHeight() - y * 2);
281 	  return destination;
282   }
283 }