1 package prefuse.util.display; 2 3 import java.awt.geom.AffineTransform ; 4 import java.awt.geom.Rectangle2D ; 5 import java.util.logging.Logger ; 6 7 12 public class Clip { 13 14 private static final byte EMPTY = 0; 15 private static final byte INUSE = 1; 16 private static final byte INVALID = 2; 17 18 private double[] clip = new double[8]; 19 private byte status = INVALID; 20 21 24 public void reset() { 25 status = EMPTY; 26 } 27 28 31 public void invalidate() { 32 status = INVALID; 33 } 34 35 39 public void setClip(Clip c) { 40 status = INUSE; 41 System.arraycopy(c.clip, 0, clip, 0, clip.length); 42 } 43 44 48 public void setClip(Rectangle2D r) { 49 setClip(r.getX(),r.getY(),r.getWidth(),r.getHeight()); 50 } 51 52 59 public void setClip(double x, double y, double w, double h) { 60 status = INUSE; 61 clip[0] = x; 62 clip[1] = y; 63 clip[6] = x+w; 64 clip[7] = y+h; 65 } 66 67 72 public void transform(AffineTransform at) { 73 clip[2] = clip[0]; clip[3] = clip[7]; 75 clip[4] = clip[6]; clip[5] = clip[1]; 76 77 at.transform(clip,0,clip,0,4); 79 80 double xmin = clip[0], ymin = clip[1]; 82 double xmax = clip[6], ymax = clip[7]; 83 for ( int i=0; i<7; i+=2 ) { 84 if ( clip[i] < xmin ) 85 xmin = clip[i]; 86 if ( clip[i] > xmax ) 87 xmax = clip[i]; 88 if ( clip[i+1] < ymin ) 89 ymin = clip[i+1]; 90 if ( clip[i+1] > ymax ) 91 ymax = clip[i+1]; 92 } 93 clip[0] = xmin; clip[1] = ymin; 94 clip[6] = xmax; clip[7] = ymax; 95 } 96 97 104 public void limit(double x1, double y1, double x2, double y2) { 105 clip[0] = Math.max(clip[0],x1); 106 clip[1] = Math.max(clip[1],y1); 107 clip[6] = Math.min(clip[6],x2); 108 clip[7] = Math.min(clip[7],y2); 109 } 110 111 118 public boolean intersects(Rectangle2D r, double margin) { 119 double tw = clip[6]-clip[0]; 120 double th = clip[7]-clip[1]; 121 double rw = r.getWidth(); 122 double rh = r.getHeight(); 123 if (rw < 0 || rh < 0 || tw < 0 || th < 0) { 124 return false; 125 } 126 double tx = clip[0]; 127 double ty = clip[1]; 128 double rx = r.getX()-margin; 129 double ry = r.getY()-margin; 130 rw += rx+2*margin; 131 rh += ry+2*margin; 132 tw += tx; 133 th += ty; 134 return ((rw < rx || rw > tx) && 136 (rh < ry || rh > ty) && 137 (tw < tx || tw > rx) && 138 (th < ty || th > ry)); 139 } 140 141 146 public void union(Clip c) { 147 if ( status == INVALID ) 148 return; 149 if ( status == EMPTY ) { 150 setClip(c); 151 status = INUSE; 152 return; 153 } 154 clip[0] = Math.min(clip[0], c.clip[0]); 155 clip[1] = Math.min(clip[1], c.clip[1]); 156 clip[6] = Math.max(clip[6], c.clip[6]); 157 clip[7] = Math.max(clip[7], c.clip[7]); 158 } 159 160 165 public void union(Rectangle2D r) { 166 if ( status == INVALID ) 167 return; 168 169 double minx = r.getMinX(); 170 double miny = r.getMinY(); 171 double maxx = r.getMaxX(); 172 double maxy = r.getMaxY(); 173 174 if ( Double.isNaN(minx) || Double.isNaN(miny) || 175 Double.isNaN(maxx) || Double.isNaN(maxy) ) { 176 Logger.getLogger(getClass().getName()).warning( 177 "Union with invalid clip region: "+r); 178 return; 179 } 180 181 if ( status == EMPTY ) { 182 setClip(r); 183 status = INUSE; 184 return; 185 } 186 clip[0] = Math.min(clip[0], minx); 187 clip[1] = Math.min(clip[1], miny); 188 clip[6] = Math.max(clip[6], maxx); 189 clip[7] = Math.max(clip[7], maxy); 190 } 191 192 200 public void union(double x, double y, double w, double h) { 201 if ( status == INVALID ) 202 return; 203 if ( status == EMPTY ) { 204 setClip(x,y,w,h); 205 status = INUSE; 206 return; 207 } 208 clip[0] = Math.min(clip[0], x); 209 clip[1] = Math.min(clip[1], y); 210 clip[6] = Math.max(clip[6], x+w); 211 clip[7] = Math.max(clip[7], y+h); 212 } 213 214 219 public void intersection(Clip c) { 220 if ( status == INVALID ) 221 return; 222 if ( status == EMPTY ) { 223 setClip(c); 224 status = INUSE; 225 return; 226 } 227 clip[0] = Math.max(clip[0], c.clip[0]); 228 clip[1] = Math.max(clip[1], c.clip[1]); 229 clip[6] = Math.min(clip[6], c.clip[6]); 230 clip[7] = Math.min(clip[7], c.clip[7]); 231 } 232 233 238 public void intersection(Rectangle2D r) { 239 if ( status == INVALID ) 240 return; 241 if ( status == EMPTY ) { 242 setClip(r); 243 status = INUSE; 244 return; 245 } 246 clip[0] = Math.max(clip[0], r.getMinX()); 247 clip[1] = Math.max(clip[1], r.getMinY()); 248 clip[6] = Math.min(clip[6], r.getMaxX()); 249 clip[7] = Math.min(clip[7], r.getMaxY()); 250 } 251 252 260 public void intersection(double x, double y, double w, double h) { 261 if ( status == INVALID ) 262 return; 263 if ( status == EMPTY ) { 264 setClip(x,y,w,h); 265 status = INUSE; 266 return; 267 } 268 clip[0] = Math.max(clip[0], x); 269 clip[1] = Math.max(clip[1], y); 270 clip[6] = Math.min(clip[6], x+w); 271 clip[7] = Math.min(clip[7], y+h); 272 } 273 274 277 public void expandToIntegerLimits() { 278 clip[0] = Math.floor(clip[0]); 279 clip[1] = Math.floor(clip[1]); 280 clip[6] = Math.ceil(clip[6]); 281 clip[7] = Math.ceil(clip[7]); 282 } 283 284 288 public void expand(double b) { 289 clip[0] -= b; clip[1] -= b; 290 clip[6] += b; clip[7] += b; 291 } 292 293 298 public void grow(double b) { 299 clip[6] += b; clip[7] += b; 300 } 301 302 306 public double getMinX() { 307 return clip[0]; 308 } 309 310 314 public double getMinY() { 315 return clip[1]; 316 } 317 318 322 public double getMaxX() { 323 return clip[6]; 324 } 325 326 330 public double getMaxY() { 331 return clip[7]; 332 } 333 334 338 public double getWidth() { 339 return clip[6]-clip[0]; 340 } 341 342 346 public double getHeight() { 347 return clip[7]-clip[1]; 348 } 349 350 354 public boolean isEmpty() { 355 return status==EMPTY; 356 } 357 358 362 public boolean isInvalid() { 363 return status==INVALID; 364 } 365 366 368 371 public boolean equals(Object o) { 372 if ( o instanceof Rectangle2D ) { 373 Rectangle2D r = (Rectangle2D )o; 374 return ( r.getMinX()==clip[0] && r.getMinY()==clip[1] && 375 r.getMaxX()==clip[6] && r.getMaxY()==clip[7] ); 376 } else if ( o instanceof Clip ) { 377 Clip r = (Clip)o; 378 if ( r.status == status ) { 379 if ( status == Clip.INUSE ) 380 return ( r.clip[0]==clip[0] && r.clip[1]==clip[1] && 381 r.clip[6]==clip[6] && r.clip[7]==clip[7] ); 382 else 383 return true; 384 } else { 385 return false; 386 } 387 } else { 388 return false; 389 } 390 } 391 392 395 public String toString() { 396 StringBuffer sb = new StringBuffer (20); 397 sb.append("Clip["); 398 switch (status) { 399 case INVALID: 400 sb.append("invalid"); 401 break; 402 case EMPTY: 403 sb.append("empty"); 404 break; 405 default: 406 sb.append(clip[0]).append(","); 407 sb.append(clip[1]).append(","); 408 sb.append(clip[6]).append(","); 409 sb.append(clip[7]); 410 } 411 sb.append("]"); 412 return sb.toString(); 413 } 414 415 } | Popular Tags |