Java Code Examples for java.awt.Shape#getPathIterator()

The following examples show how to use java.awt.Shape#getPathIterator() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
/**
 * Returns a string containing the coordinates for a given shape.  This
 * string is intended for use in an image map.
 *
 * @param shape  the shape (<code>null</code> not permitted).
 *
 * @return The coordinates for a given shape as string.
 */
private String getPolyCoords(Shape shape) {
    ParamChecks.nullNotPermitted(shape, "shape");
    StringBuilder result = new StringBuilder();
    boolean first = true;
    float[] coords = new float[6];
    PathIterator pi = shape.getPathIterator(null, 1.0);
    while (!pi.isDone()) {
        pi.currentSegment(coords);
        if (first) {
            first = false;
            result.append((int) coords[0]);
            result.append(",").append((int) coords[1]);
        }
        else {
            result.append(",");
            result.append((int) coords[0]);
            result.append(",");
            result.append((int) coords[1]);
        }
        pi.next();
    }
    return result.toString();
}
 
Example 2
Source Project: hottub   File: Path2D.java    License: GNU General Public License v2.0 6 votes vote down vote up
/**
 * Constructs a new single precision {@code Path2D} object
 * from an arbitrary {@link Shape} object, transformed by an
 * {@link AffineTransform} object.
 * All of the initial geometry and the winding rule for this path are
 * taken from the specified {@code Shape} object and transformed
 * by the specified {@code AffineTransform} object.
 *
 * @param s the specified {@code Shape} object
 * @param at the specified {@code AffineTransform} object
 * @since 1.6
 */
public Float(Shape s, AffineTransform at) {
    if (s instanceof Path2D) {
        Path2D p2d = (Path2D) s;
        setWindingRule(p2d.windingRule);
        this.numTypes = p2d.numTypes;
        // trim arrays:
        this.pointTypes = Arrays.copyOf(p2d.pointTypes, p2d.numTypes);
        this.numCoords = p2d.numCoords;
        this.floatCoords = p2d.cloneCoordsFloat(at);
    } else {
        PathIterator pi = s.getPathIterator(at);
        setWindingRule(pi.getWindingRule());
        this.pointTypes = new byte[INIT_SIZE];
        this.floatCoords = new float[INIT_SIZE * 2];
        append(pi, false);
    }
}
 
Example 3
/**
 * Returns a string containing the coordinates for a given shape.  This
 * string is intended for use in an image map.
 *
 * @param shape  the shape (<code>null</code> not permitted).
 *
 * @return The coordinates for a given shape as string.
 */
private String getPolyCoords(Shape shape) {
    ParamChecks.nullNotPermitted(shape, "shape");
    StringBuilder result = new StringBuilder();
    boolean first = true;
    float[] coords = new float[6];
    PathIterator pi = shape.getPathIterator(null, 1.0);
    while (!pi.isDone()) {
        pi.currentSegment(coords);
        if (first) {
            first = false;
            result.append((int) coords[0]);
            result.append(",").append((int) coords[1]);
        }
        else {
            result.append(",");
            result.append((int) coords[0]);
            result.append(",");
            result.append((int) coords[1]);
        }
        pi.next();
    }
    return result.toString();
}
 
Example 4
/**
 * Returns a string containing the coordinates for a given shape.  This
 * string is intended for use in an image map.
 *
 * @param shape  the shape (<code>null</code> not permitted).
 *
 * @return The coordinates for a given shape as string.
 */
private String getPolyCoords(Shape shape) {
    ParamChecks.nullNotPermitted(shape, "shape");
    StringBuilder result = new StringBuilder();
    boolean first = true;
    float[] coords = new float[6];
    PathIterator pi = shape.getPathIterator(null, 1.0);
    while (!pi.isDone()) {
        pi.currentSegment(coords);
        if (first) {
            first = false;
            result.append((int) coords[0]);
            result.append(",").append((int) coords[1]);
        }
        else {
            result.append(",");
            result.append((int) coords[0]);
            result.append(",");
            result.append((int) coords[1]);
        }
        pi.next();
    }
    return result.toString();
}
 
Example 5
/**
 * Constructs a new double precision {@code Path2D} object
 * from an arbitrary {@link Shape} object, transformed by an
 * {@link AffineTransform} object.
 * All of the initial geometry and the winding rule for this path are
 * taken from the specified {@code Shape} object and transformed
 * by the specified {@code AffineTransform} object.
 *
 * @param s the specified {@code Shape} object
 * @param at the specified {@code AffineTransform} object
 * @since 1.6
 */
public Double(Shape s, AffineTransform at) {
    if (s instanceof Path2D) {
        Path2D p2d = (Path2D) s;
        setWindingRule(p2d.windingRule);
        this.numTypes = p2d.numTypes;
        // trim arrays:
        this.pointTypes = Arrays.copyOf(p2d.pointTypes, p2d.numTypes);
        this.numCoords = p2d.numCoords;
        this.doubleCoords = p2d.cloneCoordsDouble(at);
    } else {
        PathIterator pi = s.getPathIterator(at);
        setWindingRule(pi.getWindingRule());
        this.pointTypes = new byte[INIT_SIZE];
        this.doubleCoords = new double[INIT_SIZE * 2];
        append(pi, false);
    }
}
 
Example 6
/**
 * Constructs a new single precision {@code Path2D} object
 * from an arbitrary {@link Shape} object, transformed by an
 * {@link AffineTransform} object.
 * All of the initial geometry and the winding rule for this path are
 * taken from the specified {@code Shape} object and transformed
 * by the specified {@code AffineTransform} object.
 *
 * @param s the specified {@code Shape} object
 * @param at the specified {@code AffineTransform} object
 * @since 1.6
 */
public Float(Shape s, AffineTransform at) {
    if (s instanceof Path2D) {
        Path2D p2d = (Path2D) s;
        setWindingRule(p2d.windingRule);
        this.numTypes = p2d.numTypes;
        // trim arrays:
        this.pointTypes = Arrays.copyOf(p2d.pointTypes, p2d.numTypes);
        this.numCoords = p2d.numCoords;
        this.floatCoords = p2d.cloneCoordsFloat(at);
    } else {
        PathIterator pi = s.getPathIterator(at);
        setWindingRule(pi.getWindingRule());
        this.pointTypes = new byte[INIT_SIZE];
        this.floatCoords = new float[INIT_SIZE * 2];
        append(pi, false);
    }
}
 
Example 7
Source Project: jdk-1.7-annotated   File: Path2D.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Constructs a new single precision {@code Path2D} object
 * from an arbitrary {@link Shape} object, transformed by an
 * {@link AffineTransform} object.
 * All of the initial geometry and the winding rule for this path are
 * taken from the specified {@code Shape} object and transformed
 * by the specified {@code AffineTransform} object.
 *
 * @param s the specified {@code Shape} object
 * @param at the specified {@code AffineTransform} object
 * @since 1.6
 */
public Float(Shape s, AffineTransform at) {
    if (s instanceof Path2D) {
        Path2D p2d = (Path2D) s;
        setWindingRule(p2d.windingRule);
        this.numTypes = p2d.numTypes;
        this.pointTypes = Arrays.copyOf(p2d.pointTypes,
                                        p2d.pointTypes.length);
        this.numCoords = p2d.numCoords;
        this.floatCoords = p2d.cloneCoordsFloat(at);
    } else {
        PathIterator pi = s.getPathIterator(at);
        setWindingRule(pi.getWindingRule());
        this.pointTypes = new byte[INIT_SIZE];
        this.floatCoords = new float[INIT_SIZE * 2];
        append(pi, false);
    }
}
 
Example 8
public Shape mapShape(Shape s) {
    if (LOGMAP) LOG.format("mapshape on path: %s\n", LayoutPathImpl.SegmentPath.this);
    PathIterator pi = s.getPathIterator(null, 1); // cheap way to handle curves.

    if (LOGMAP) LOG.format("start\n");
    init();

    final double[] coords = new double[2];
    while (!pi.isDone()) {
        switch (pi.currentSegment(coords)) {
        case SEG_CLOSE: close(); break;
        case SEG_MOVETO: moveTo(coords[0], coords[1]); break;
        case SEG_LINETO: lineTo(coords[0], coords[1]); break;
        default: break;
        }

        pi.next();
    }
    if (LOGMAP) LOG.format("finish\n\n");

    GeneralPath gp = new GeneralPath();
    for (Segment seg: segments) {
        gp.append(seg.gp, false);
    }
    return gp;
}
 
Example 9
public Shape mapShape(Shape s) {
    if (LOGMAP) LOG.format("mapshape on path: %s\n", LayoutPathImpl.SegmentPath.this);
    PathIterator pi = s.getPathIterator(null, 1); // cheap way to handle curves.

    if (LOGMAP) LOG.format("start\n");
    init();

    final double[] coords = new double[2];
    while (!pi.isDone()) {
        switch (pi.currentSegment(coords)) {
        case SEG_CLOSE: close(); break;
        case SEG_MOVETO: moveTo(coords[0], coords[1]); break;
        case SEG_LINETO: lineTo(coords[0], coords[1]); break;
        default: break;
        }

        pi.next();
    }
    if (LOGMAP) LOG.format("finish\n\n");

    GeneralPath gp = new GeneralPath();
    for (Segment seg: segments) {
        gp.append(seg.gp, false);
    }
    return gp;
}
 
Example 10
Source Project: mil-sym-java   File: lineutility.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Creates a GeneralPath from a Path2D
 *
 * @param shape
 * @return
 */
protected static Shape createStrokedShape(Shape shape) {
    GeneralPath newshape = new GeneralPath(); // Start with an empty shape
    try {
        // Iterate through the specified shape, perturb its coordinates, and
        // use them to build up the new shape.
        float[] coords = new float[6];
        for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i.next()) {
            int type = i.currentSegment(coords);
            switch (type) {
                case PathIterator.SEG_MOVETO:
                    //perturb(coords, 2);
                    newshape.moveTo(coords[0], coords[1]);
                    break;
                case PathIterator.SEG_LINETO:
                    //perturb(coords, 2);
                    newshape.lineTo(coords[0], coords[1]);
                    break;
                case PathIterator.SEG_QUADTO:
                    //perturb(coords, 4);
                    newshape.quadTo(coords[0], coords[1], coords[2], coords[3]);
                    break;
                case PathIterator.SEG_CUBICTO:
                    //perturb(coords, 6);
                    newshape.curveTo(coords[0], coords[1], coords[2], coords[3],
                            coords[4], coords[5]);
                    break;
                case PathIterator.SEG_CLOSE:
                    newshape.closePath();
                    break;
            }

        }
    } catch (Exception exc) {
        ErrorLogger.LogException(_className, "createStrokedShape",
                new RendererException("Failed inside createStrokedShape", exc));
    }
    return newshape;
}
 
Example 11
/**
 * This method calculates shape intersection with line.
 *
 * @param shape
 * @param line
 * @return Intersection point
 */
private static Point getShapeIntersection(Shape shape, Line2D.Double line) {
    PathIterator it = shape.getPathIterator(null);
    double[] coords = new double[6];
    double[] pos = new double[2];
    Line2D.Double l = new Line2D.Double();
    while (!it.isDone()) {
        int type = it.currentSegment(coords);
        switch (type) {
        case PathIterator.SEG_MOVETO:
            pos[0] = coords[0];
            pos[1] = coords[1];
            break;
        case PathIterator.SEG_LINETO:
            l = new Line2D.Double(pos[0], pos[1], coords[0], coords[1]);
            if (line.intersectsLine(l)) {
                return getLinesIntersection(line, l);
            }
            pos[0] = coords[0];
            pos[1] = coords[1];
            break;
        case PathIterator.SEG_CLOSE:
            break;
        default:
            // whatever
        }
        it.next();
    }
    return null;
}
 
Example 12
@Override
public Shape createStrokedShape(Shape shape)
{
	GeneralPath newshape = new GeneralPath(); // Start with an empty shape

	// Iterate through the specified shape, perturb its coordinates, and
	// use them to build up the new shape.
	float[] coords = new float[6];
	for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i
			.next())
	{
		int type = i.currentSegment(coords);
		switch (type)
		{
		case PathIterator.SEG_MOVETO:
			perturb(coords, 2);
			newshape.moveTo(coords[0], coords[1]);
			break;
		case PathIterator.SEG_LINETO:
			perturb(coords, 2);
			newshape.lineTo(coords[0], coords[1]);
			break;
		case PathIterator.SEG_QUADTO:
			perturb(coords, 4);
			newshape.quadTo(coords[0], coords[1], coords[2], coords[3]);
			break;
		case PathIterator.SEG_CUBICTO:
			perturb(coords, 6);
			newshape.curveTo(coords[0], coords[1], coords[2], coords[3],
					coords[4], coords[5]);
			break;
		case PathIterator.SEG_CLOSE:
			newshape.closePath();
			break;
		}
	}

	// Finally, stroke the perturbed shape and return the result
	return stroke.createStrokedShape(newshape);
}
 
Example 13
@Override
public void write(Shape s) {
    PathIterator iter = s.getPathIterator(null);
    write(iter);
}
 
Example 14
/**
 * {@inheritDoc}
 */
@Override
public void strokeTo(Shape src,
                     AffineTransform transform,
                     BasicStroke bs,
                     boolean thin,
                     boolean normalize,
                     boolean antialias,
                     PathConsumer2D sr)
{
    PathStroker stroker = new PathStroker(sr);
    PathConsumer consumer = stroker;

    float matrix[] = null;
    if (!thin) {
        stroker.setPenDiameter(bs.getLineWidth());
        if (transform != null) {
            matrix = getTransformMatrix(transform);
        }
        stroker.setPenT4(matrix);
        stroker.setPenFitting(PenUnits, MinPenUnits);
    }
    stroker.setCaps(RasterizerCaps[bs.getEndCap()]);
    stroker.setCorners(RasterizerCorners[bs.getLineJoin()],
                       bs.getMiterLimit());
    float[] dashes = bs.getDashArray();
    if (dashes != null) {
        PathDasher dasher = new PathDasher(stroker);
        dasher.setDash(dashes, bs.getDashPhase());
        if (transform != null && matrix == null) {
            matrix = getTransformMatrix(transform);
        }
        dasher.setDashT4(matrix);
        consumer = dasher;
    }

    try {
        PathIterator pi = src.getPathIterator(transform);

        feedConsumer(pi, consumer, normalize, 0.25f);
    } catch (PathException e) {
        throw new InternalError("Unable to Stroke shape ("+
                                e.getMessage()+")", e);
    } finally {
        while (consumer != null && consumer != sr) {
            PathConsumer next = consumer.getConsumer();
            consumer.dispose();
            consumer = next;
        }
    }
}
 
Example 15
@Override
    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 SEG_MOVETO:
                    moveX = lastX = points[0];
                    moveY = lastY = points[1];
                    result.moveTo(moveX, moveY);
                    next = wavelength / 2;
                    break;

                case SEG_CLOSE:
                    points[0] = moveX;
                    points[1] = moveY;
                    // fall through

                case 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;
                    lastX = thisX;
                    lastY = thisY;
                    if (type == SEG_CLOSE) {
                        result.closePath();
                    }
                    break;
            }
            it.next();
        }

        return stroke.createStrokedShape(result);
    }
 
Example 16
/**
 * {@inheritDoc}
 */
@Override
public void strokeTo(Shape src,
                     AffineTransform transform,
                     BasicStroke bs,
                     boolean thin,
                     boolean normalize,
                     boolean antialias,
                     PathConsumer2D sr)
{
    PathStroker stroker = new PathStroker(sr);
    PathConsumer consumer = stroker;

    float matrix[] = null;
    if (!thin) {
        stroker.setPenDiameter(bs.getLineWidth());
        if (transform != null) {
            matrix = getTransformMatrix(transform);
        }
        stroker.setPenT4(matrix);
        stroker.setPenFitting(PenUnits, MinPenUnits);
    }
    stroker.setCaps(RasterizerCaps[bs.getEndCap()]);
    stroker.setCorners(RasterizerCorners[bs.getLineJoin()],
                       bs.getMiterLimit());
    float[] dashes = bs.getDashArray();
    if (dashes != null) {
        PathDasher dasher = new PathDasher(stroker);
        dasher.setDash(dashes, bs.getDashPhase());
        if (transform != null && matrix == null) {
            matrix = getTransformMatrix(transform);
        }
        dasher.setDashT4(matrix);
        consumer = dasher;
    }

    try {
        PathIterator pi = src.getPathIterator(transform);

        feedConsumer(pi, consumer, normalize, 0.25f);
    } catch (PathException e) {
        throw new InternalError("Unable to Stroke shape ("+
                                e.getMessage()+")", e);
    } finally {
        while (consumer != null && consumer != sr) {
            PathConsumer next = consumer.getConsumer();
            consumer.dispose();
            consumer = next;
        }
    }
}
 
Example 17
/** Draws a shape. */
public OurPDFWriter drawShape(Shape shape, boolean fillOrNot) {
    if (shape instanceof Polygon) {
        Polygon obj = (Polygon) shape;
        for (int i = 0; i < obj.npoints; i++)
            buf.writes(obj.xpoints[i]).writes(obj.ypoints[i]).write(i == 0 ? "m\n" : "l\n");
        buf.write("h\n");
    } else {
        double moveX = 0, moveY = 0, nowX = 0, nowY = 0, pt[] = new double[6];
        for (PathIterator it = shape.getPathIterator(null); !it.isDone(); it.next())
            switch (it.currentSegment(pt)) {
                case PathIterator.SEG_MOVETO :
                    nowX = moveX = pt[0];
                    nowY = moveY = pt[1];
                    buf.writes(nowX).writes(nowY).write("m\n");
                    break;
                case PathIterator.SEG_CLOSE :
                    nowX = moveX;
                    nowY = moveY;
                    buf.write("h\n");
                    break;
                case PathIterator.SEG_LINETO :
                    nowX = pt[0];
                    nowY = pt[1];
                    buf.writes(nowX).writes(nowY).write("l\n");
                    break;
                case PathIterator.SEG_CUBICTO :
                    nowX = pt[4];
                    nowY = pt[5];
                    buf.writes(pt[0]).writes(pt[1]).writes(pt[2]).writes(pt[3]).writes(nowX).writes(nowY).write("c\n");
                    break;
                case PathIterator.SEG_QUADTO : // Convert quadratic bezier
                                              // into cubic bezier using
                                              // de Casteljau algorithm
                    double px = nowX + (pt[0] - nowX) * (2.0 / 3.0), qx = px + (pt[2] - nowX) / 3.0;
                    double py = nowY + (pt[1] - nowY) * (2.0 / 3.0), qy = py + (pt[3] - nowY) / 3.0;
                    nowX = pt[2];
                    nowY = pt[3];
                    buf.writes(px).writes(py).writes(qx).writes(qy).writes(nowX).writes(nowY).write("c\n");
                    break;
            }
    }
    buf.write(fillOrNot ? "f\n" : "S\n");
    return this;
}
 
Example 18
private static void serializeShape(Shape shape) {
    final double[] coords = new double[6];

    final int len = 32;
    final ArrayList<Integer> typeList = new ArrayList<Integer>(len);
    final ArrayList<double[]> coordsList = new ArrayList<double[]>(len);

    for (PathIterator pi = shape.getPathIterator(null);
            !pi.isDone(); pi.next())
    {
        switch (pi.currentSegment(coords)) {
            case SEG_MOVETO:
                typeList.add(SEG_MOVETO);
                coordsList.add(Arrays.copyOf(coords, 2));
                break;
            case SEG_LINETO:
                typeList.add(SEG_LINETO);
                coordsList.add(Arrays.copyOf(coords, 2));
                break;
            case SEG_QUADTO:
                typeList.add(SEG_QUADTO);
                coordsList.add(Arrays.copyOf(coords, 4));
                break;
            case SEG_CUBICTO:
                typeList.add(SEG_CUBICTO);
                coordsList.add(Arrays.copyOf(coords, 6));
                break;
            case SEG_CLOSE:
                typeList.add(SEG_CLOSE);
                coordsList.add(null);
                break;
            default:
        }
    }

    final StringBuilder sb = new StringBuilder(1024);
    // types:
    sb.append("private static final int[] SHAPE_TYPES = new int[]{\n");
    for (Integer i : typeList) {
        sb.append(i).append(",\n");
    }
    sb.append("};\n");

    // coords:
    sb.append("private static final double[][] SHAPE_COORDS = new double[][]{\n");
    for (double[] c : coordsList) {
        if (c == null) {
            sb.append("null,\n");
        } else {
            sb.append("new double[]{");
            for (int i = 0; i < c.length; i++) {
                sb.append(c[i]).append(",");
            }
            sb.append("},\n");
        }
    }
    sb.append("};\n");

    System.out.println("Shape size: " + typeList.size());
    System.out.println("Serialized shape:\n" + sb.toString());
}
 
Example 19
/**
 * Get a reverse transformed flattened path iterator for a shape.
 *
 * @param shape       shape for which a reverse transformed flattened path
 *                    iterator is needed
 * @param at          the affine transform
 * @param flatness    flatness epsilon
 * @param windingRule winding rule of newly created iterator
 * @return reverse transformed flattened path iterator
 */
public static PathIterator getReversePathIterator (Shape shape,
                                                   AffineTransform at,
                                                   double flatness,
                                                   int windingRule)
{
    return new ReversePathIterator(shape.getPathIterator(at, flatness), windingRule);
}
 
Example 20
/**
 * Construct an antialiased tile generator for the given shape with
 * the given rendering attributes and store the bounds of the tile
 * iteration in the bbox parameter.
 * The {@code at} parameter specifies a transform that should affect
 * both the shape and the {@code BasicStroke} attributes.
 * The {@code clip} parameter specifies the current clip in effect
 * in device coordinates and can be used to prune the data for the
 * operation, but the renderer is not required to perform any
 * clipping.
 * If the {@code BasicStroke} parameter is null then the shape
 * should be filled as is, otherwise the attributes of the
 * {@code BasicStroke} should be used to specify a draw operation.
 * The {@code thin} parameter indicates whether or not the
 * transformed {@code BasicStroke} represents coordinates smaller
 * than the minimum resolution of the antialiasing rasterizer as
 * specified by the {@code getMinimumAAPenWidth()} method.
 * <p>
 * Upon returning, this method will fill the {@code bbox} parameter
 * with 4 values indicating the bounds of the iteration of the
 * tile generator.
 * The iteration order of the tiles will be as specified by the
 * pseudo-code:
 * <pre>
 *     for (y = bbox[1]; y < bbox[3]; y += tileheight) {
 *         for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
 *         }
 *     }
 * </pre>
 * If there is no output to be rendered, this method may return
 * null.
 *
 * @param s the shape to be rendered (fill or draw)
 * @param at the transform to be applied to the shape and the
 *           stroke attributes
 * @param clip the current clip in effect in device coordinates
 * @param bs if non-null, a {@code BasicStroke} whose attributes
 *           should be applied to this operation
 * @param thin true if the transformed stroke attributes are smaller
 *             than the minimum dropout pen width
 * @param normalize true if the {@code VALUE_STROKE_NORMALIZE}
 *                  {@code RenderingHint} is in effect
 * @param bbox returns the bounds of the iteration
 * @return the {@code AATileGenerator} instance to be consulted
 *         for tile coverages, or null if there is no output to render
 * @since 1.7
 */
public AATileGenerator getAATileGenerator(Shape s,
                                          AffineTransform at,
                                          Region clip,
                                          BasicStroke bs,
                                          boolean thin,
                                          boolean normalize,
                                          int bbox[])
{
    Renderer r;
    NormMode norm = (normalize) ? NormMode.ON_WITH_AA : NormMode.OFF;
    if (bs == null) {
        PathIterator pi;
        if (normalize) {
            pi = new NormalizingPathIterator(s.getPathIterator(at), norm);
        } else {
            pi = s.getPathIterator(at);
        }
        r = new Renderer(3, 3,
                         clip.getLoX(), clip.getLoY(),
                         clip.getWidth(), clip.getHeight(),
                         pi.getWindingRule());
        pathTo(pi, r);
    } else {
        r = new Renderer(3, 3,
                         clip.getLoX(), clip.getLoY(),
                         clip.getWidth(), clip.getHeight(),
                         PathIterator.WIND_NON_ZERO);
        strokeTo(s, at, bs, thin, norm, true, r);
    }
    r.endRendering();
    PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA);
    ptg.getBbox(bbox);
    return ptg;
}