java.awt.Shape#getPathIterator ( )源码实例Demo

下面列出了java.awt.Shape#getPathIterator ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: openstock   文件: ChartEntity.java
/**
 * 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();
}
 
源代码2 项目: hottub   文件: Path2D.java
/**
 * 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);
    }
}
 
源代码3 项目: ECG-Viewer   文件: ChartEntity.java
/**
 * 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();
}
 
源代码4 项目: ccu-historian   文件: ChartEntity.java
/**
 * 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();
}
 
源代码5 项目: openjdk-jdk9   文件: Path2D.java
/**
 * 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);
    }
}
 
源代码6 项目: openjdk-jdk9   文件: Path2D.java
/**
 * 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);
    }
}
 
源代码7 项目: jdk-1.7-annotated   文件: Path2D.java
/**
 * 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);
    }
}
 
源代码8 项目: openjdk-8   文件: LayoutPathImpl.java
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;
}
 
源代码9 项目: openjdk-jdk9   文件: LayoutPathImpl.java
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;
}
 
源代码10 项目: mil-sym-java   文件: lineutility.java
/**
 * 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;
}
 
源代码11 项目: flowable-engine   文件: DefaultCaseDiagramCanvas.java
/**
 * 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;
}
 
源代码12 项目: han3_ji7_tsoo1_kian3   文件: AwtStrokeExample.java
@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);
}
 
源代码13 项目: Pixelitor   文件: CalligraphyPathWriter.java
@Override
public void write(Shape s) {
    PathIterator iter = s.getPathIterator(null);
    write(iter);
}
 
源代码14 项目: jdk8u-jdk   文件: DuctusRenderingEngine.java
/**
 * {@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;
        }
    }
}
 
源代码15 项目: Pixelitor   文件: ZigzagStroke.java
@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);
    }
 
源代码16 项目: TencentKona-8   文件: DuctusRenderingEngine.java
/**
 * {@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;
        }
    }
}
 
源代码17 项目: org.alloytools.alloy   文件: OurPDFWriter.java
/** 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;
}
 
源代码18 项目: openjdk-jdk9   文件: TextClipErrorTest.java
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());
}
 
源代码19 项目: audiveris   文件: ReversePathIterator.java
/**
 * 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);
}
 
源代码20 项目: dragonwell8_jdk   文件: PiscesRenderingEngine.java
/**
 * 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;
}