⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generalpath.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)GeneralPath.java	1.58 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.awt.geom;import java.awt.Shape;import sun.awt.geom.Curve;import sun.awt.geom.Crossings;/** * The <code>GeneralPath</code> class represents a geometric path  * constructed from straight lines, and quadratic and cubic * (B&eacute;zier) curves.  It can contain multiple subpaths. * <p> * The winding rule specifies how the interior of a path is * determined.  There are two types of winding rules:   * EVEN_ODD and NON_ZERO. * <p> * An EVEN_ODD winding rule means that enclosed regions * of the path alternate between interior and exterior areas as * traversed from the outside of the path towards a point inside * the region.   * <p> * A NON_ZERO winding rule means that if a ray is  * drawn in any direction from a given point to infinity * and the places where the path intersects * the ray are examined, the point is inside of the path if and only if * the number of times that the path crosses the ray from * left to right does not equal the  number of times that the path crosses * the ray from right to left.   * @version 1.58, 01/23/03 * @author Jim Graham */public final class GeneralPath implements Shape, Cloneable {    /**     * An even-odd winding rule for determining the interior of     * a path.       */    public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;    /**     * A non-zero winding rule for determining the interior of a     * path.       */    public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;        // For code simplicity, copy these constants to our namespace    // and cast them to byte constants for easy storage.    private static final byte SEG_MOVETO  = (byte) PathIterator.SEG_MOVETO;    private static final byte SEG_LINETO  = (byte) PathIterator.SEG_LINETO;    private static final byte SEG_QUADTO  = (byte) PathIterator.SEG_QUADTO;    private static final byte SEG_CUBICTO = (byte) PathIterator.SEG_CUBICTO;    private static final byte SEG_CLOSE   = (byte) PathIterator.SEG_CLOSE;    byte[] pointTypes;    float[] pointCoords;    int numTypes;    int numCoords;    int windingRule;    static final int INIT_SIZE = 20;    static final int EXPAND_MAX = 500;    /**     * Constructs a new <code>GeneralPath</code> object.     * If an operation performed on this path requires the     * interior of the path to be defined then the default NON_ZERO     * winding rule is used.     * @see #WIND_NON_ZERO     */    public GeneralPath() {	this(WIND_NON_ZERO, INIT_SIZE, INIT_SIZE);    }    /**     * Constructs a new <code>GeneralPath</code> object with the specified      * winding rule to control operations that require the interior of the     * path to be defined.     * @param rule the winding rule     * @see #WIND_EVEN_ODD     * @see #WIND_NON_ZERO     */    public GeneralPath(int rule) {	this(rule, INIT_SIZE, INIT_SIZE);    }    /**     * Constructs a new <code>GeneralPath</code> object with the specified      * winding rule and the specified initial capacity to store path      * coordinates. This number is an initial guess as to how many path      * segments are in the path, but the storage is expanded      * as needed to store whatever path segments are added to this path.     * @param rule the winding rule     * @param initialCapacity the estimate for the number of path segments     * in the path     * @see #WIND_EVEN_ODD     * @see #WIND_NON_ZERO     */    public GeneralPath(int rule, int initialCapacity) {	this(rule, initialCapacity, initialCapacity);    }    /**     * Constructs a new <code>GeneralPath</code> object with the specified      * winding rule and the specified initial capacities to store point types     * and coordinates.     * These numbers are an initial guess as to how many path segments     * and how many points are to be in the path, but the     * storage is expanded as needed to store whatever path segments are     * added to this path.     * @param rule the winding rule     * @param initialTypes the estimate for the number of path segments     * in the path     * @param initialCapacity the estimate for the number of points     * @see #WIND_EVEN_ODD     * @see #WIND_NON_ZERO     */    GeneralPath(int rule, int initialTypes, int initialCoords) {	setWindingRule(rule);	pointTypes = new byte[initialTypes];	pointCoords = new float[initialCoords * 2];    }    /**     * Constructs a new <code>GeneralPath</code> object from an arbitrary      * {@link Shape} object.     * All of the initial geometry and the winding rule for this path are     * taken from the specified <code>Shape</code> object.     * @param s the specified <code>Shape</code> object     */    public GeneralPath(Shape s) {	this(WIND_NON_ZERO, INIT_SIZE, INIT_SIZE);	PathIterator pi = s.getPathIterator(null);	setWindingRule(pi.getWindingRule());	append(pi, false);    }     private void needRoom(int newTypes, int newCoords, boolean needMove) {	if (needMove && numTypes == 0) {	    throw new IllegalPathStateException("missing initial moveto "+						"in path definition");	}	int size = pointCoords.length;	if (numCoords + newCoords > size) {	    int grow = size;	    if (grow > EXPAND_MAX * 2) {		grow = EXPAND_MAX * 2;	    }	    if (grow < newCoords) {		grow = newCoords;	    }	    float[] arr = new float[size + grow];	    System.arraycopy(pointCoords, 0, arr, 0, numCoords);	    pointCoords = arr;	}	size = pointTypes.length;	if (numTypes + newTypes > size) {	    int grow = size;	    if (grow > EXPAND_MAX) {		grow = EXPAND_MAX;	    }	    if (grow < newTypes) {		grow = newTypes;	    }	    byte[] arr = new byte[size + grow];	    System.arraycopy(pointTypes, 0, arr, 0, numTypes);	    pointTypes = arr;	}    }    /**     * Adds a point to the path by moving to the specified     * coordinates.     * @param x,&nbsp;y the specified coordinates     */    public synchronized void moveTo(float x, float y) {	if (numTypes > 0 && pointTypes[numTypes - 1] == SEG_MOVETO) {	    pointCoords[numCoords - 2] = x;	    pointCoords[numCoords - 1] = y;	} else {	    needRoom(1, 2, false);	    pointTypes[numTypes++] = SEG_MOVETO;	    pointCoords[numCoords++] = x;	    pointCoords[numCoords++] = y;	}    }    /**     * Adds a point to the path by drawing a straight line from the     * current coordinates to the new specified coordinates.     * @param x,&nbsp;y the specified coordinates     */    public synchronized void lineTo(float x, float y) {	needRoom(1, 2, true);	pointTypes[numTypes++] = SEG_LINETO;	pointCoords[numCoords++] = x;	pointCoords[numCoords++] = y;    }    /**     * Adds a curved segment, defined by two new points, to the path by     * drawing a Quadratic curve that intersects both the current     * coordinates and the coordinates (x2,&nbsp;y2), using the      * specified point (x1,&nbsp;y1) as a quadratic parametric control     * point.     * @param x1,&nbsp;y1 the coordinates of the first quadratic control     *		point     * @param x2,&nbsp;y2 the coordinates of the final endpoint     */    public synchronized void quadTo(float x1, float y1, float x2, float y2) {	needRoom(1, 4, true);	pointTypes[numTypes++] = SEG_QUADTO;	pointCoords[numCoords++] = x1;	pointCoords[numCoords++] = y1;	pointCoords[numCoords++] = x2;	pointCoords[numCoords++] = y2;    }    /**     * Adds a curved segment, defined by three new points, to the path by     * drawing a B&eacute;zier curve that intersects both the current     * coordinates and the coordinates (x3,&nbsp;y3), using the         * specified points (x1,&nbsp;y1) and (x2,&nbsp;y2) as     * B&eacute;zier control points.     * @param x1,&nbsp;y1 the coordinates of the first B&eacute;ezier     *		control point     * @param x2,&nbsp;y2 the coordinates of the second B&eacute;zier     *		control point     * @param x3,&nbsp;y3 the coordinates of the final endpoint     */    public synchronized void curveTo(float x1, float y1,				     float x2, float y2,				     float x3, float y3) {	needRoom(1, 6, true);	pointTypes[numTypes++] = SEG_CUBICTO;	pointCoords[numCoords++] = x1;	pointCoords[numCoords++] = y1;	pointCoords[numCoords++] = x2;	pointCoords[numCoords++] = y2;	pointCoords[numCoords++] = x3;	pointCoords[numCoords++] = y3;    }    /**     * Closes the current subpath by drawing a straight line back to     * the coordinates of the last <code>moveTo</code>.  If the path is already     * closed then this method has no effect.     */    public synchronized void closePath() {	if (numTypes == 0 || pointTypes[numTypes - 1] != SEG_CLOSE) {	    needRoom(1, 0, true);	    pointTypes[numTypes++] = SEG_CLOSE;	}    }    /**     * Appends the geometry of the specified <code>Shape</code> object to the     * path, possibly connecting the new geometry to the existing path     * segments with a line segment.     * If the <code>connect</code> parameter is <code>true</code> and the      * path is not empty then any initial <code>moveTo</code> in the     * geometry of the appended <code>Shape</code>     * is turned into a <code>lineTo</code> segment.     * If the destination coordinates of such a connecting <code>lineTo</code>     * segment match the ending coordinates of a currently open     * subpath then the segment is omitted as superfluous.     * The winding rule of the specified <code>Shape</code> is ignored     * and the appended geometry is governed by the winding     * rule specified for this path.     * @param s the <code>Shape</code> whose geometry is appended      * to this path     * @param connect a boolean to control whether or not to turn an     * initial <code>moveTo</code> segment into a <code>lineTo</code>     * segment to connect the new geometry to the existing path     */    public void append(Shape s, boolean connect) {	PathIterator pi = s.getPathIterator(null);        append(pi,connect);    }    /**     * Appends the geometry of the specified     * {@link PathIterator} object      * to the path, possibly connecting the new geometry to the existing     * path segments with a line segment.     * If the <code>connect</code> parameter is <code>true</code> and the      * path is not empty then any initial <code>moveTo</code> in the     * geometry of the appended <code>Shape</code> is turned into a     * <code>lineTo</code> segment.     * If the destination coordinates of such a connecting <code>lineTo</code>     * segment match the ending coordinates of a currently open     * subpath then the segment is omitted as superfluous.     * The winding rule of the specified <code>Shape</code> is ignored     * and the appended geometry is governed by the winding     * rule specified for this path.     * @param pi the <code>PathIterator</code> whose geometry is appended to      * this path     * @param connect a boolean to control whether or not to turn an     * initial <code>moveTo</code> segment into a <code>lineTo</code> segment     * to connect the new geometry to the existing path     */    public void append(PathIterator pi, boolean connect) {	float coords[] = new float[6];	while (!pi.isDone()) {	    switch (pi.currentSegment(coords)) {	    case SEG_MOVETO:		if (!connect || numTypes < 1 || numCoords < 2) {		    moveTo(coords[0], coords[1]);		    break;		}		if (pointTypes[numTypes - 1] != SEG_CLOSE &&		    pointCoords[numCoords - 2] == coords[0] &&		    pointCoords[numCoords - 1] == coords[1])		{		    // Collapse out initial moveto/lineto

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -