001/*
002 * $Id: PolylineShape.java 4784 2011-03-15 08:33:00Z blowagie $
003 *
004 * This file is part of the iText (R) project.
005 * Copyright (c) 1998-2011 1T3XT BVBA
006 * Authors: Bruno Lowagie, Paulo Soares, et al.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU Affero General Public License version 3
010 * as published by the Free Software Foundation with the addition of the
011 * following permission added to Section 15 as permitted in Section 7(a):
012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT,
013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
014 *
015 * This program is distributed in the hope that it will be useful, but
016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
017 * or FITNESS FOR A PARTICULAR PURPOSE.
018 * See the GNU Affero General Public License for more details.
019 * You should have received a copy of the GNU Affero General Public License
020 * along with this program; if not, see http://www.gnu.org/licenses or write to
021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
022 * Boston, MA, 02110-1301 USA, or download the license from the following URL:
023 * http://itextpdf.com/terms-of-use/
024 *
025 * The interactive user interfaces in modified source and object code versions
026 * of this program must display Appropriate Legal Notices, as required under
027 * Section 5 of the GNU Affero General Public License.
028 *
029 * In accordance with Section 7(b) of the GNU Affero General Public License,
030 * a covered work must retain the producer line in every PDF that is created
031 * or manipulated using iText.
032 *
033 * You can be released from the requirements of the license by purchasing
034 * a commercial license. Buying such a license is mandatory as soon as you
035 * develop commercial activities involving the iText software without
036 * disclosing the source code of your own applications.
037 * These activities include: offering paid services to customers as an ASP,
038 * serving PDFs on the fly in a web application, shipping iText with a closed
039 * source product.
040 *
041 * For more information, please contact iText Software Corp. at this
042 * address: sales@itextpdf.com
043 */
044package com.itextpdf.text.pdf.internal;
045
046import java.awt.Shape;
047import java.awt.Rectangle;
048import java.awt.geom.AffineTransform;
049import java.awt.geom.PathIterator;
050import java.awt.geom.Line2D;
051import java.awt.geom.Point2D;
052import java.awt.geom.Rectangle2D;
053
054/**
055 * Class that defines a Polyline shape.
056 * This class was originally written by wil - amristar.com.au
057 * and integrated into iText by Bruno.
058 */
059public class PolylineShape implements Shape {
060        /** All the X-values of the coordinates in the polyline. */
061        protected int[] x;
062        /** All the Y-values of the coordinates in the polyline. */
063        protected int[] y;
064        /** The total number of points. */
065        protected int np;
066
067        /** Creates a PolylineShape. */
068        public PolylineShape(int[] x, int[] y, int nPoints) {
069                // Should copy array (as done in Polygon)
070                this.np = nPoints;
071                // Take a copy.
072                this.x = new int[np];
073                this.y = new int[np];
074                System.arraycopy(x, 0, this.x, 0, np);
075                System.arraycopy(y, 0, this.y, 0, np);
076        }
077
078        /**
079         * Returns the bounding box of this polyline.
080         *
081         * @return a {@link Rectangle2D} that is the high-precision
082         *      bounding box of this line.
083         * @see java.awt.Shape#getBounds2D()
084         */
085        public Rectangle2D getBounds2D() {
086                int[] r = rect();
087                return r==null?null:new Rectangle2D.Double(r[0], r[1], r[2], r[3]);
088        }
089        
090        /**
091         * Returns the bounding box of this polyline.
092         * @see java.awt.Shape#getBounds()
093         */
094        public Rectangle getBounds() {
095                return getBounds2D().getBounds();
096        }
097
098        /**
099         * Calculates the origin (X, Y) and the width and height
100         * of a rectangle that contains all the segments of the
101         * polyline.
102         */
103        private int[] rect() {
104                 if(np==0)return null;
105                int xMin = x[0], yMin=y[0], xMax=x[0],yMax=y[0];
106
107                 for(int i=1;i<np;i++) {
108                         if(x[i]<xMin)xMin=x[i];
109                         else if(x[i]>xMax)xMax=x[i];
110                         if(y[i]<yMin)yMin=y[i];
111                         else if(y[i]>yMax)yMax=y[i];
112                 }
113
114                 return new int[] { xMin, yMin, xMax-xMin, yMax-yMin };
115        }
116
117        /**
118         * A polyline can't contain a point.
119         * @see java.awt.Shape#contains(double, double)
120         */
121        public boolean contains(double x, double y) { return false; }
122        
123        /**
124         * A polyline can't contain a point.
125         * @see java.awt.Shape#contains(java.awt.geom.Point2D)
126         */
127        public boolean contains(Point2D p) { return false; }
128        
129        /**
130         * A polyline can't contain a point.
131         * @see java.awt.Shape#contains(double, double, double, double)
132         */
133        public boolean contains(double x, double y, double w, double h) { return false; }
134        
135        /**
136         * A polyline can't contain a point.
137         * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
138         */
139        public boolean contains(Rectangle2D r) { return false; }
140
141        /**
142         * Checks if one of the lines in the polyline intersects
143         * with a given rectangle.
144         * @see java.awt.Shape#intersects(double, double, double, double)
145         */
146        public boolean intersects(double x, double y, double w, double h) {
147                return intersects(new Rectangle2D.Double(x, y, w, h));
148        }
149
150        /**
151         * Checks if one of the lines in the polyline intersects
152         * with a given rectangle.
153         * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
154         */
155        public boolean intersects(Rectangle2D r) {
156                if(np==0)return false;
157                Line2D line = new Line2D.Double(x[0],y[0],x[0],y[0]);
158                for (int i = 1; i < np; i++) {
159                        line.setLine(x[i-1], y[i-1], x[i], y[i]);
160                        if(line.intersects(r))return true;
161                }
162                return false;
163        }
164
165        /**
166         * Returns an iteration object that defines the boundary of the polyline.
167         * @param at the specified {@link AffineTransform}
168         * @return a {@link PathIterator} that defines the boundary of this polyline.
169         * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
170         */
171        public PathIterator getPathIterator(AffineTransform at) {
172                return new PolylineShapeIterator(this, at);
173        }
174
175        /**
176         * There's no difference with getPathIterator(AffineTransform at);
177         * we just need this method to implement the Shape interface.
178         */
179        public PathIterator getPathIterator(AffineTransform at, double flatness) {
180                return new PolylineShapeIterator(this, at);
181        }
182
183}
184