// draws the image along the path private void drawWithGraphicsStroke( Graphics2D graphics, Shape shape, Style2D graphicStroke, boolean isLabelObstacle) { PathIterator pi = shape.getPathIterator(null); double[] coords = new double[4]; int type; // I suppose the image has been already scaled and its square double imageSize; double graphicRotation = 0; // rotation in radians if (graphicStroke instanceof MarkStyle2D) { imageSize = ((MarkStyle2D) graphicStroke).getSize(); graphicRotation = ((MarkStyle2D) graphicStroke).getRotation(); } else if (graphicStroke instanceof IconStyle2D) { imageSize = ((IconStyle2D) graphicStroke).getIcon().getIconWidth(); graphicRotation = ((IconStyle2D) graphicStroke).getRotation(); } else { GraphicStyle2D gs = (GraphicStyle2D) graphicStroke; imageSize = gs.getImage().getWidth() - gs.getBorder(); graphicRotation = ((GraphicStyle2D) graphicStroke).getRotation(); } Composite composite = ((PointStyle2D) graphicStroke).getComposite(); if (composite == null) { composite = AlphaComposite.SrcOver; } double[] first = new double[2]; double[] previous = new double[2]; type = pi.currentSegment(coords); first[0] = coords[0]; first[1] = coords[1]; previous[0] = coords[0]; previous[1] = coords[1]; if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("starting at " + first[0] + "," + first[1]); } pi.next(); double remainder, dx, dy, len; remainder = imageSize / 2.0; while (!pi.isDone()) { type = pi.currentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: // nothing to do? if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("moving to " + coords[0] + "," + coords[1]); } first[0] = coords[0]; first[1] = coords[1]; remainder = imageSize / 2.0; break; case PathIterator.SEG_CLOSE: // draw back to first from previous coords[0] = first[0]; coords[1] = first[1]; remainder = imageSize / 2.0; if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest( "closing from " + previous[0] + "," + previous[1] + " to " + coords[0] + "," + coords[1]); } // no break here - fall through to next section case PathIterator.SEG_LINETO: // draw from previous to coords if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest( "drawing from " + previous[0] + "," + previous[1] + " to " + coords[0] + "," + coords[1]); } dx = coords[0] - previous[0]; dy = coords[1] - previous[1]; len = Math.sqrt((dx * dx) + (dy * dy)); // - imageWidth; if (len < remainder) { remainder -= len; } else { double theta = Math.atan2(dx, dy); dx = (Math.sin(theta) * imageSize); dy = (Math.cos(theta) * imageSize); if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest( "dx = " + dx + " dy " + dy + " step = " + Math.sqrt((dx * dx) + (dy * dy))); } double rotation = -(theta - (Math.PI / 2d)); double x = previous[0] + (Math.sin(theta) * remainder); double y = previous[1] + (Math.cos(theta) * remainder); if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("len =" + len + " imageSize " + imageSize); } double dist = 0; for (dist = remainder; dist < len; dist += imageSize) { renderGraphicsStroke( graphics, x, y, graphicStroke, rotation, graphicRotation, composite, isLabelObstacle); x += dx; y += dy; } remainder = dist - len; if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("loop end dist " + dist + " len " + len + " " + (len - dist)); } } break; default: LOGGER.warning("default branch reached in drawWithGraphicStroke"); } previous[0] = coords[0]; previous[1] = coords[1]; pi.next(); } }