graphicslib.java

来自「用applet实现很多应用小程序」· Java 代码 · 共 791 行 · 第 1/3 页

JAVA
791
字号
        
        if ( len < 6 ) {
            throw new IllegalArgumentException(
                    "To create spline requires at least 3 points");
        }
        
        float dx1, dy1, dx2, dy2;
        // compute first control point
        if ( closed ) {
            dx2 = pts[start+2]-pts[end-2];
            dy2 = pts[start+3]-pts[end-1];
        } else {
            dx2 = pts[start+4]-pts[start];
            dy2 = pts[start+5]-pts[start+1];
        }
        
        // repeatedly compute next control point and append curve
        int i;
        for ( i=start+2; i<end-2; i+=2 ) {
            dx1 = dx2; dy1 = dy2;
            dx2 = pts[i+2]-pts[i-2];
            dy2 = pts[i+3]-pts[i-1];            
            if ( Math.abs(pts[i]  -pts[i-2]) < epsilon ||
                 Math.abs(pts[i+1]-pts[i-1]) < epsilon )
            {
                p.lineTo(tx+pts[i], ty+pts[i+1]);
            } else {
                p.curveTo(tx+pts[i-2]+slack*dx1, ty+pts[i-1]+slack*dy1,
                          tx+pts[i]  -slack*dx2, ty+pts[i+1]-slack*dy2,
                          tx+pts[i],             ty+pts[i+1]);
            }
        }
        
        // compute last control point
        dx1 = dx2; dy1 = dy2;
        dx2 = pts[start]-pts[i-2];
        dy2 = pts[start+1]-pts[i-1];
        if ( Math.abs(pts[i]  -pts[i-2]) < epsilon ||
             Math.abs(pts[i+1]-pts[i-1]) < epsilon )
        {
             p.lineTo(tx+pts[i], ty+pts[i+1]);
        } else {
            p.curveTo(tx+pts[i-2]+slack*dx1, ty+pts[i-1]+slack*dy1,
                      tx+pts[i]  -slack*dx2, ty+pts[i+1]-slack*dy2,
                      tx+pts[i],             ty+pts[i+1]);
        }
        
        // close the curve if requested
        if ( closed ) {    
            if ( Math.abs(pts[end-2]-pts[0]) < epsilon ||
                 Math.abs(pts[end-1]-pts[1]) < epsilon )
            {
                p.lineTo(tx+pts[0], ty+pts[1]);
            } else {
                dx1 = dx2; dy1 = dy2;
                dx2 = pts[start+2]-pts[end-2];
                dy2 = pts[start+3]-pts[end-1];
                p.curveTo(tx+pts[end-2]+slack*dx1, ty+pts[end-1]+slack*dy1,
                          tx+pts[0]    -slack*dx2, ty+pts[1]    -slack*dy2,
                          tx+pts[0],               ty+pts[1]);
            }
            p.closePath();
        }
        return p;
    }
    
    /**
     * Expand a rectangle by the given amount.
     * @param r the rectangle to expand
     * @param amount the amount by which to expand the rectangle
     */
    public static void expand(Rectangle2D r, double amount) {
        r.setRect(r.getX()-amount, r.getY()-amount,
                  r.getWidth()+2*amount, r.getHeight()+2*amount);
    }
    
    // ------------------------------------------------------------------------
    
    /**
     * Sets a VisualItem's bounds based on its shape and stroke type. This
     * method is optimized to avoid calling .getBounds2D where it can, thus
     * avoiding object initialization and reducing object churn.
     * @param item the VisualItem whose bounds are to be set
     * @param shape a Shape from which to determine the item bounds
     * @param stroke the stroke type that will be used for drawing the object,
     * and may affect the final bounds. A null value indicates the
     * default (line width = 1) stroke is used.
     */
    public static void setBounds(VisualItem item,
                                 Shape shape, BasicStroke stroke)
    {
        double x, y, w, h, lw, lw2;
        
        if ( shape instanceof RectangularShape ) {
            // this covers rectangle, rounded rectangle, ellipse, and arcs
            RectangularShape r = (RectangularShape)shape;
            x = r.getX();
            y = r.getY();
            w = r.getWidth();
            h = r.getHeight();
        } else if ( shape instanceof Line2D ) {
            // this covers straight lines
            Line2D l = (Line2D)shape;
            x = l.getX1();
            y = l.getY1();
            w = l.getX2();
            h = l.getY2();
            if ( w < x ) {
                lw = x;
                x = w;
                w = lw-x;
            } else {
                w = w-x;
            }
            if ( h < y ) {
                lw = y;
                y = h;
                h = lw-y;
            } else {
                h = h-y;
            }
        } else {
            // this covers any other arbitrary shapes, but
            // takes a small object allocation / garbage collection hit
            Rectangle2D r = shape.getBounds2D();
            x = r.getX();
            y = r.getY();
            w = r.getWidth();
            h = r.getHeight();
        }
        
        // adjust boundary for stoke length as necessary
        if ( stroke != null && (lw=stroke.getLineWidth()) > 1 ) {
            lw2 = lw/2.0;
            x -= lw2; y -= lw2; w += lw; h += lw;
        }
        item.setBounds(x, y, w, h);
    }
    
    /**
     * Render a shape associated with a VisualItem into a graphics context. This
     * method uses the {@link java.awt.Graphics} interface methods when it can,
     * as opposed to the {@link java.awt.Graphics2D} methods such as
     * {@link java.awt.Graphics2D#draw(java.awt.Shape)} and
     * {@link java.awt.Graphics2D#fill(java.awt.Shape)}, resulting in a
     * significant performance increase on the Windows platform, particularly
     * for rectangle and line drawing calls.
     * @param g the graphics context to render to
     * @param item the item being represented by the shape, this instance is
     * used to get the correct color values for the drawing
     * @param shape the shape to render
     * @param stroke the stroke type to use for drawing the object.
     * @param type the rendering type indicating if the shape should be drawn,
     * filled, or both. One of
     * {@link prefuse.render.AbstractShapeRenderer#RENDER_TYPE_DRAW},
     * {@link prefuse.render.AbstractShapeRenderer#RENDER_TYPE_FILL},
     * {@link prefuse.render.AbstractShapeRenderer#RENDER_TYPE_DRAW_AND_FILL}, or
     * {@link prefuse.render.AbstractShapeRenderer#RENDER_TYPE_NONE}.
     */
    public static void paint(Graphics2D g, VisualItem item,
                             Shape shape, BasicStroke stroke, int type)
    {
        // if render type is NONE, then there is nothing to do
        if ( type == AbstractShapeRenderer.RENDER_TYPE_NONE )
            return;
        
        // set up colors
        Color strokeColor = ColorLib.getColor(item.getStrokeColor());
        Color fillColor = ColorLib.getColor(item.getFillColor());
        boolean sdraw = (type == AbstractShapeRenderer.RENDER_TYPE_DRAW ||
                         type == AbstractShapeRenderer.RENDER_TYPE_DRAW_AND_FILL) &&
                        strokeColor.getAlpha() != 0;
        boolean fdraw = (type == AbstractShapeRenderer.RENDER_TYPE_FILL ||
                         type == AbstractShapeRenderer.RENDER_TYPE_DRAW_AND_FILL) &&
                        fillColor.getAlpha() != 0;
        if ( !(sdraw || fdraw) ) return;
        
        Stroke origStroke = null;
        if ( sdraw ) {
            origStroke = g.getStroke();
            g.setStroke(stroke);
        }
        
        int x, y, w, h, aw, ah;
        double xx, yy, ww, hh;

        // see if an optimized (non-shape) rendering call is available for us
        // these can speed things up significantly on the windows JRE
        // it is stupid we have to do this, but we do what we must
        // if we are zoomed in, we have no choice but to use
        // full precision rendering methods.
        AffineTransform at = g.getTransform();
        double scale = Math.max(at.getScaleX(), at.getScaleY());
        if ( scale > 1.5 ) {
            if (fdraw) { g.setPaint(fillColor);   g.fill(shape); }
            if (sdraw) { g.setPaint(strokeColor); g.draw(shape); }
        }
        else if ( shape instanceof RectangularShape )
        {
            RectangularShape r = (RectangularShape)shape;
            xx = r.getX(); ww = r.getWidth(); 
            yy = r.getY(); hh = r.getHeight();
            
            x = (int)xx;
            y = (int)yy;
            w = (int)(ww+xx-x);
            h = (int)(hh+yy-y);
            
            if ( shape instanceof Rectangle2D ) {
                if (fdraw) {
                    g.setPaint(fillColor);
                    g.fillRect(x, y, w, h);
                }
                if (sdraw) {
                    g.setPaint(strokeColor);
                    g.drawRect(x, y, w, h);
                }
            } else if ( shape instanceof RoundRectangle2D ) {
                RoundRectangle2D rr = (RoundRectangle2D)shape;
                aw = (int)rr.getArcWidth();
                ah = (int)rr.getArcHeight();
                if (fdraw) {
                    g.setPaint(fillColor);
                    g.fillRoundRect(x, y, w, h, aw, ah);
                }
                if (sdraw) {
                    g.setPaint(strokeColor);
                    g.drawRoundRect(x, y, w, h, aw, ah);
                }
            } else if ( shape instanceof Ellipse2D ) {
                if (fdraw) {
                    g.setPaint(fillColor);
                    g.fillOval(x, y, w, h);
                }
                if (sdraw) {
                    g.setPaint(strokeColor);
                    g.drawOval(x, y, w, h);
                }
            } else {
                if (fdraw) { g.setPaint(fillColor);   g.fill(shape); }
                if (sdraw) { g.setPaint(strokeColor); g.draw(shape); }
            }
        } else if ( shape instanceof Line2D ) {
            if (sdraw) {
                Line2D l = (Line2D)shape;
                x = (int)(l.getX1()+0.5);
                y = (int)(l.getY1()+0.5);
                w = (int)(l.getX2()+0.5);
                h = (int)(l.getY2()+0.5);
                g.setPaint(strokeColor);
                g.drawLine(x, y, w, h);
            }
        } else {
            if (fdraw) { g.setPaint(fillColor);   g.fill(shape); }
            if (sdraw) { g.setPaint(strokeColor); g.draw(shape); }
        }
        if ( sdraw ) {
            g.setStroke(origStroke);
        }
    }
    
} // end of class GraphicsLib

⌨️ 快捷键说明

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