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 + -
显示快捷键?