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 }