* 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; } public AATileGenerator getAATileGenerator(double x, double y, double dx1, double dy1, double dx2, double dy2, double lw1, double lw2, Region clip, int bbox[]) { // REMIND: Deal with large coordinates! double ldx1, ldy1, ldx2, ldy2; boolean innerpgram = (lw1 > 0 && lw2 > 0); if (innerpgram) { ldx1 = dx1 * lw1; ldy1 = dy1 * lw1; ldx2 = dx2 * lw2; ldy2 = dy2 * lw2; x -= (ldx1 + ldx2) / 2.0; y -= (ldy1 + ldy2) / 2.0; dx1 += ldx1; dy1 += ldy1; dx2 += ldx2; dy2 += ldy2; if (lw1 > 1 && lw2 > 1) { // Inner parallelogram was entirely consumed by stroke... innerpgram = false; } } else { ldx1 = ldy1 = ldx2 = ldy2 = 0; } Renderer r = new Renderer(3, 3, clip.getLoX(), clip.getLoY(), clip.getWidth(), clip.getHeight(), PathIterator.WIND_EVEN_ODD); r.moveTo((float) x, (float) y); r.lineTo((float) (x+dx1), (float) (y+dy1)); r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); r.lineTo((float) (x+dx2), (float) (y+dy2)); r.closePath(); if (innerpgram) { x += ldx1 + ldx2; y += ldy1 + ldy2; dx1 -= 2.0 * ldx1; dy1 -= 2.0 * ldy1; dx2 -= 2.0 * ldx2; dy2 -= 2.0 * ldy2; r.moveTo((float) x, (float) y); r.lineTo((float) (x+dx1), (float) (y+dy1)); r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); r.lineTo((float) (x+dx2), (float) (y+dy2)); r.closePath(); } r.pathDone(); r.endRendering(); PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA); ptg.getBbox(bbox); return ptg; } /** * Returns the minimum pen width that the antialiasing rasterizer * can represent without dropouts occuring. * @since 1.7 */ public float getMinimumAAPenSize() { return 0.5f; } static { if (PathIterator.WIND_NON_ZERO != Renderer.WIND_NON_ZERO || PathIterator.WIND_EVEN_ODD != Renderer.WIND_EVEN_ODD || BasicStroke.JOIN_MITER != Stroker.JOIN_MITER || BasicStroke.JOIN_ROUND != Stroker.JOIN_ROUND || BasicStroke.JOIN_BEVEL != Stroker.JOIN_BEVEL || BasicStroke.CAP_BUTT != Stroker.CAP_BUTT || BasicStroke.CAP_ROUND != Stroker.CAP_ROUND || BasicStroke.CAP_SQUARE != Stroker.CAP_SQUARE) { throw new InternalError("mismatched renderer constants"); } }} Lines 501–656 of 656. Previous lines
* 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; } public AATileGenerator getAATileGenerator(double x, double y, double dx1, double dy1, double dx2, double dy2, double lw1, double lw2, Region clip, int bbox[]) { // REMIND: Deal with large coordinates! double ldx1, ldy1, ldx2, ldy2; boolean innerpgram = (lw1 > 0 && lw2 > 0); if (innerpgram) { ldx1 = dx1 * lw1; ldy1 = dy1 * lw1; ldx2 = dx2 * lw2; ldy2 = dy2 * lw2; x -= (ldx1 + ldx2) / 2.0; y -= (ldy1 + ldy2) / 2.0; dx1 += ldx1; dy1 += ldy1; dx2 += ldx2; dy2 += ldy2; if (lw1 > 1 && lw2 > 1) { // Inner parallelogram was entirely consumed by stroke... innerpgram = false; } } else { ldx1 = ldy1 = ldx2 = ldy2 = 0; } Renderer r = new Renderer(3, 3, clip.getLoX(), clip.getLoY(), clip.getWidth(), clip.getHeight(), PathIterator.WIND_EVEN_ODD); r.moveTo((float) x, (float) y); r.lineTo((float) (x+dx1), (float) (y+dy1)); r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); r.lineTo((float) (x+dx2), (float) (y+dy2)); r.closePath(); if (innerpgram) { x += ldx1 + ldx2; y += ldy1 + ldy2; dx1 -= 2.0 * ldx1; dy1 -= 2.0 * ldy1; dx2 -= 2.0 * ldx2; dy2 -= 2.0 * ldy2; r.moveTo((float) x, (float) y); r.lineTo((float) (x+dx1), (float) (y+dy1)); r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); r.lineTo((float) (x+dx2), (float) (y+dy2)); r.closePath(); } r.pathDone(); r.endRendering(); PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA); ptg.getBbox(bbox); return ptg; } /** * Returns the minimum pen width that the antialiasing rasterizer * can represent without dropouts occuring. * @since 1.7 */ public float getMinimumAAPenSize() { return 0.5f; } static { if (PathIterator.WIND_NON_ZERO != Renderer.WIND_NON_ZERO || PathIterator.WIND_EVEN_ODD != Renderer.WIND_EVEN_ODD || BasicStroke.JOIN_MITER != Stroker.JOIN_MITER || BasicStroke.JOIN_ROUND != Stroker.JOIN_ROUND || BasicStroke.JOIN_BEVEL != Stroker.JOIN_BEVEL || BasicStroke.CAP_BUTT != Stroker.CAP_BUTT || BasicStroke.CAP_ROUND != Stroker.CAP_ROUND || BasicStroke.CAP_SQUARE != Stroker.CAP_SQUARE) { throw new InternalError("mismatched renderer constants"); } } }