/** * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>, * <code>nohref</code> Attribute for the specified figure and shape. * * @return Returns true, if the polygon is inside of the image bounds. */ private boolean writePolyAttributes(IXMLElement elem, SVGFigure f, Shape shape) { AffineTransform t = TRANSFORM.getClone(f); if (t == null) { t = drawingTransform; } else { t.preConcatenate(drawingTransform); } StringBuilder buf = new StringBuilder(); float[] coords = new float[6]; GeneralPath path = new GeneralPath(); for (PathIterator i = shape.getPathIterator(t, 1.5f); ! i.isDone(); i.next()) { switch (i.currentSegment(coords)) { case PathIterator.SEG_MOVETO : if (buf.length() != 0) { throw new IllegalArgumentException("Illegal shape "+shape); } if (buf.length() != 0) { buf.append(','); } buf.append((int) coords[0]); buf.append(','); buf.append((int) coords[1]); path.moveTo(coords[0], coords[1]); break; case PathIterator.SEG_LINETO : if (buf.length() != 0) { buf.append(','); } buf.append((int) coords[0]); buf.append(','); buf.append((int) coords[1]); path.lineTo(coords[0], coords[1]); break; case PathIterator.SEG_CLOSE : path.closePath(); break; default : throw new InternalError("Illegal segment type "+i.currentSegment(coords)); } } elem.setAttribute("shape", "poly"); elem.setAttribute("coords", buf.toString()); writeHrefAttribute(elem, f); return path.intersects(new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height)); }
public void addGlyph(GlyphData gv, float x, float y) { AffineTransform at = AffineTransform.getTranslateInstance(x, y); PathIterator pi = gv.gp.getPathIterator(at); float[] coords = new float[6]; while (!pi.isDone()) { int type = pi.currentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: moveTo(coords[0], coords[1]); break; case PathIterator.SEG_LINETO: lineTo(coords[0], coords[1]); break; case PathIterator.SEG_CUBICTO: curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case PathIterator.SEG_CLOSE: closePath(); break; default: System.out.println("Unknown path type: " + type); break; } pi.next(); } }
/** * Wrapper method around the <tt>paintText()</tt> method of the <tt>VisualEdgePainter</tt> * interface. This method performs the calculation to determine the position where the text will * be drawn. */ private void paintText(VisualEdge vEdge, Graphics2D g2d) { Point fromPoint = new Point(); Point toPoint = new Point(); GeneralPath gPath = vEdge.getGeneralPath(); PathIterator iterator = gPath.getPathIterator(null); FontMetrics fontMetrics; float edgeSegment[] = new float[6]; double currentLength = 0; float cumulativeLength = 0; float x1 = 0, y1 = 0, x2 = 0, y2 = 0; int segmentType; boolean firstPointInitialized = false; // Get the total length of the edge float edgeLength = vEdge.getEdgeLength(vEdge, fromPoint, toPoint); while (!iterator.isDone()) { segmentType = iterator.currentSegment(edgeSegment); switch (segmentType) { case PathIterator.SEG_LINETO: case PathIterator.SEG_MOVETO: x2 = edgeSegment[0]; y2 = edgeSegment[1]; break; case PathIterator.SEG_QUADTO: x2 = edgeSegment[2]; y2 = edgeSegment[3]; break; case PathIterator.SEG_CUBICTO: x2 = edgeSegment[4]; y2 = edgeSegment[5]; } if (firstPointInitialized) { currentLength = Point2D.distance(x1, y1, x2, y2); cumulativeLength += currentLength; } iterator.next(); // If we are halfway through the length of the edge, // then paint the text if (cumulativeLength >= (edgeLength / 2) || cumulativeLength >= edgeLength) { // Ratio of the remaining half-length over the length of the current edge double ratio = ((edgeLength / 2) - (cumulativeLength - currentLength)) / currentLength; fontMetrics = vEdge.getFontMetrics(); // Take into account the text's length this.paintText( g2d, vEdge.getFont(), vEdge.getFontcolor(), vEdge.getLabel(), (float) (fromPoint.getX() < toPoint.getX() ? (x1 + (Math.abs(x2 - x1) * ratio)) : (x1 - (Math.abs(x2 - x1) * ratio))) - fontMetrics.stringWidth(vEdge.getLabel()) / 2, (float) (fromPoint.getY() < toPoint.getY() ? (y1 + (Math.abs(y2 - y1) * ratio)) : (y1 - (Math.abs(y2 - y1) * ratio)))); break; } x1 = x2; y1 = y2; if (!firstPointInitialized) { firstPointInitialized = true; } } }
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; boolean first = false; float next = 0; int phase = 0; float factor = 1; 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); first = true; 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; float angle = (float) Math.atan2(dy, dx); while (distance >= next) { float x = lastX + next * dx * r; float y = lastY + next * dy * r; float tx = amplitude * dy * r; float ty = amplitude * dx * 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; first = false; lastX = thisX; lastY = thisY; if (type == PathIterator.SEG_CLOSE) result.closePath(); break; } it.next(); } // return stroke.createStrokedShape( result ); return result; }