/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.renderer.style.shape; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** * Decorator on top of the {@link Shape}. It extends the Shape interface to include a method * 'setBounds' for explicitly defining a bounding box (which is not necessarily associated with the * actual shape's bounds). * * @author fmoura * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/render/src/main/java/org/geotools/renderer/style/shape/ExplicitBoundsShape.java $ */ public class ExplicitBoundsShape implements Shape { private Shape shape; private Rectangle2D bounds = null; /** * The Constructor * * @param shape * The actual shape on top of which this decorator will stand. */ public ExplicitBoundsShape(Shape shape) { if (shape == null) throw new IllegalArgumentException("Shape can't be null."); this.shape = shape; } /** * Sets the explicitly defined bounds for this shape. * * @param bounds */ public void setBounds(Rectangle2D bounds) { this.bounds = bounds; } public boolean contains(double x, double y, double w, double h) { return shape.contains(x, y, w, h); } public boolean contains(double x, double y) { return shape.contains(x, y); } public boolean contains(Point2D p) { return shape.contains((Point2D) p); } public boolean contains(Rectangle2D r) { return shape.contains((Rectangle2D) r); } /** * Returns the explicitly defined bounds for this shape. If no bounds were explicitly set, it * delegates the call to the actual shape. * * @return the Rectangle representing the Shape's bounding box. * @see Shape */ public Rectangle getBounds() { if (bounds != null) return new Rectangle((int) bounds.getMinX(), (int) bounds.getMinY(), (int) bounds .getWidth(), (int) bounds.getHeight()); return shape.getBounds(); } /** * Returns the explicitly defined bounds for this shape. If no bounds were explicitly set, it * delegates the call to the actual shape. * * @return the Rectangle2D representing the Shape's bounding box. * @see Shape */ public Rectangle2D getBounds2D() { if (bounds != null) return bounds; return shape.getBounds2D(); } public PathIterator getPathIterator(AffineTransform at, double flatness) { return shape.getPathIterator(at, flatness); } public PathIterator getPathIterator(AffineTransform at) { return shape.getPathIterator(at); } public boolean intersects(double x, double y, double w, double h) { return shape.intersects(x, y, w, h); } public boolean intersects(Rectangle2D r) { return shape.intersects(r); } @Override public boolean equals(Object obj) { if (obj instanceof ExplicitBoundsShape) { ExplicitBoundsShape other = (ExplicitBoundsShape) obj; boolean result = shape.equals(other.shape); if (bounds == null) return result & (other.bounds == null); return result & bounds.equals(other.bounds); } else if (obj instanceof Shape) { if (bounds == null) return shape.equals(obj); return false; } return super.equals(obj); } @Override public int hashCode() { int hascode = shape.hashCode(); if (bounds != null) hascode += hascode * 37 + bounds.hashCode(); return hascode; } }