static { Stroke stroke = new BasicStroke(2); selectionShape = stroke.createStrokedShape(hitRect); format.setMinimumIntegerDigits(1); format.setMinimumFractionDigits(1); format.setMaximumFractionDigits(2); }
/** * Get the bounding box of the shape when stroked. This method takes account of the thickness of * the stroke. */ public Rectangle2D getBounds() { // FIXME: these bounds REALLY need to be cached. But it's // painful because of the public members. if (stroke == null) { return shape.getBounds2D(); } else if (stroke instanceof BasicStroke) { // For some reason (antialiasing?) the bounds returned by // BasicStroke is off by one. This code works around it. // if all we want is the bounds, then we don't need to actually // stroke the shape. We've had reports that this is no longer // necessary with JDK1.3. Rectangle2D rect = shape.getBounds2D(); int width = (int) ((BasicStroke) stroke).getLineWidth() + 2; return new Rectangle2D.Double( rect.getX() - width, rect.getY() - width, rect.getWidth() + width + width, rect.getHeight() + width + width); } else { // For some reason (antialiasing?) the bounds returned by // BasicStroke is off by one. This code works around it. // We've had reports that this is no longer // necessary with JDK1.3. Rectangle2D rect = stroke.createStrokedShape(shape).getBounds2D(); return new Rectangle2D.Double( rect.getX() - 1, rect.getY() - 1, rect.getWidth() + 2, rect.getHeight() + 2); } }
/** * Calculates the bounds of the line taking stroke width into account. * * @return rectangle representing the bounds of the line taking stroke width into account */ public Rectangle2D getLineBoundsWithStroke() { if (stroke != null) { return stroke.createStrokedShape(lineShape).getBounds2D(); } else { return lineShape.getBounds2D(); } }
/** @see Graphics2D#hit(Rectangle, Shape, boolean) */ public boolean hit(Rectangle rect, Shape s, boolean onStroke) { if (onStroke) { s = stroke.createStrokedShape(s); } s = transform.createTransformedShape(s); Area area = new Area(s); if (clip != null) area.intersect(clip); return area.intersects(rect.x, rect.y, rect.width, rect.height); }
/** Get the bounding box of this terminal. */ @Override public Rectangle2D getBounds() { Rectangle2D bounds = _stroke.createStrokedShape(_line).getBounds2D(); if (_end != null) { Rectangle2D.union(bounds, _end.getBounds(), bounds); } return bounds; }
/** {@inheritDoc} */ public boolean intersects(final Rectangle2D aBounds) { if (super.intersects(aBounds)) { if (lineShape.intersects(aBounds)) { return true; } else if (stroke != null && strokePaint != null) { return stroke.createStrokedShape(lineShape).intersects(aBounds); } } return false; }
public Shape createStrokedShape(Shape shape) { Area area1 = new Area(stroke1.createStrokedShape(shape)); Area area2 = new Area(stroke2.createStrokedShape(shape)); switch (operation) { case ADD: area1.add(area2); break; case SUBSTRACT: area1.subtract(area2); break; case INTERSECT: area1.intersect(area2); break; case DIFFERENCE: area1.exclusiveOr(area2); break; } return area1; }
public Shape createStrokedShape(Shape shape) { GeneralPath result = new GeneralPath(); PathIterator it = new FlatteningPathIterator(shape.getPathIterator(null), FLATNESS); float points[] = new float[6]; float moveX = 0, moveY = 0; float lastX = 0, lastY = 0; float thisX = 0, thisY = 0; int type = 0; float next = 0; int phase = 0; while (!it.isDone()) { type = it.currentSegment(points); switch (type) { case PathIterator.SEG_MOVETO: moveX = lastX = points[0]; moveY = lastY = points[1]; result.moveTo(moveX, moveY); next = wavelength / 2; break; case PathIterator.SEG_CLOSE: points[0] = moveX; points[1] = moveY; // Fall into.... case PathIterator.SEG_LINETO: thisX = points[0]; thisY = points[1]; float dx = thisX - lastX; float dy = thisY - lastY; float distance = (float) Math.sqrt(dx * dx + dy * dy); if (distance >= next) { float r = 1.0f / distance; while (distance >= next) { float x = lastX + next * dx * r; float y = lastY + next * dy * r; if ((phase & 1) == 0) result.lineTo(x + amplitude * dy * r, y - amplitude * dx * r); else result.lineTo(x - amplitude * dy * r, y + amplitude * dx * r); next += wavelength; phase++; } } next -= distance; lastX = thisX; lastY = thisY; if (type == PathIterator.SEG_CLOSE) result.closePath(); break; } it.next(); } return stroke.createStrokedShape(result); }
/** * Returns {@code true} if the rectangle (in device space) intersects with the shape (the * interior, if {@code onStroke} is false, otherwise the stroked outline of the shape). * * @param rect a rectangle (in device space). * @param s the shape. * @param onStroke test the stroked outline only? * @return A boolean. */ @Override public boolean hit(Rectangle rect, Shape s, boolean onStroke) { AffineTransform transform = getTransform(); Shape ts; if (onStroke) { Stroke stroke = getStroke(); ts = transform.createTransformedShape(stroke.createStrokedShape(s)); } else { ts = transform.createTransformedShape(s); } if (!rect.getBounds2D().intersects(ts.getBounds2D())) { return false; } Area a1 = new Area(rect); Area a2 = new Area(ts); a1.intersect(a2); return !a1.isEmpty(); }
/** Creates the composite shape */ @Override public Shape createStrokedShape(Shape shape) { return stroke2.createStrokedShape(stroke1.createStrokedShape(shape)); }
private void followPath(Shape s, int drawType) { if (s == null) return; if (drawType == STROKE) { if (!(stroke instanceof BasicStroke)) { s = stroke.createStrokedShape(s); followPath(s, FILL); return; } } if (drawType == STROKE) { setStrokeDiff(stroke, oldStroke); oldStroke = stroke; setStrokePaint(); } else if (drawType == FILL) setFillPaint(); PathIterator points; int traces = 0; if (drawType == CLIP) points = s.getPathIterator(IDENTITY); else points = s.getPathIterator(transform); float[] coords = new float[6]; while (!points.isDone()) { ++traces; int segtype = points.currentSegment(coords); normalizeY(coords); switch (segtype) { case PathIterator.SEG_CLOSE: cb.closePath(); break; case PathIterator.SEG_CUBICTO: cb.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case PathIterator.SEG_LINETO: cb.lineTo(coords[0], coords[1]); break; case PathIterator.SEG_MOVETO: cb.moveTo(coords[0], coords[1]); break; case PathIterator.SEG_QUADTO: cb.curveTo(coords[0], coords[1], coords[2], coords[3]); break; } points.next(); } switch (drawType) { case FILL: if (traces > 0) { if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) cb.eoFill(); else cb.fill(); } break; case STROKE: if (traces > 0) cb.stroke(); break; default: // drawType==CLIP if (traces == 0) cb.rectangle(0, 0, 0, 0); if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) cb.eoClip(); else cb.clip(); cb.newPath(); } }