| /* |
| * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Sun designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Sun in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| */ |
| |
| /* |
| * @author Charlton Innovations, Inc. |
| */ |
| |
| package sun.java2d.loops; |
| |
| import java.awt.image.WritableRaster; |
| import java.awt.image.DataBuffer; |
| import java.awt.image.ColorModel; |
| import java.awt.geom.Path2D; |
| import java.awt.geom.PathIterator; |
| import java.awt.geom.AffineTransform; |
| import sun.java2d.pipe.Region; |
| import sun.java2d.pipe.SpanIterator; |
| import sun.java2d.SunGraphics2D; |
| import sun.java2d.SurfaceData; |
| import sun.java2d.loops.ProcessPath; |
| import sun.font.GlyphList; |
| |
| /** |
| * GeneralRenderer collection |
| * Basically, a collection of components which permit basic |
| * rendering to occur on rasters of any format |
| */ |
| |
| public final class GeneralRenderer { |
| public static void register() { |
| Class owner = GeneralRenderer.class; |
| GraphicsPrimitive[] primitives = { |
| new GraphicsPrimitiveProxy(owner, "SetFillRectANY", |
| FillRect.methodSignature, |
| FillRect.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "SetFillPathANY", |
| FillPath.methodSignature, |
| FillPath.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "SetFillSpansANY", |
| FillSpans.methodSignature, |
| FillSpans.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "SetDrawLineANY", |
| DrawLine.methodSignature, |
| DrawLine.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY", |
| DrawPolygons.methodSignature, |
| DrawPolygons.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "SetDrawPathANY", |
| DrawPath.methodSignature, |
| DrawPath.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "SetDrawRectANY", |
| DrawRect.methodSignature, |
| DrawRect.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any), |
| |
| new GraphicsPrimitiveProxy(owner, "XorFillRectANY", |
| FillRect.methodSignature, |
| FillRect.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorFillPathANY", |
| FillPath.methodSignature, |
| FillPath.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorFillSpansANY", |
| FillSpans.methodSignature, |
| FillSpans.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorDrawLineANY", |
| DrawLine.methodSignature, |
| DrawLine.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY", |
| DrawPolygons.methodSignature, |
| DrawPolygons.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorDrawPathANY", |
| DrawPath.methodSignature, |
| DrawPath.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorDrawRectANY", |
| DrawRect.methodSignature, |
| DrawRect.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListANY", |
| DrawGlyphList.methodSignature, |
| DrawGlyphList.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListAAANY", |
| DrawGlyphListAA.methodSignature, |
| DrawGlyphListAA.primTypeID, |
| SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any), |
| }; |
| GraphicsPrimitiveMgr.register(primitives); |
| } |
| |
| static void doDrawPoly(SurfaceData sData, PixelWriter pw, |
| int xPoints[], int yPoints[], int off, int nPoints, |
| Region clip, int transx, int transy, boolean close) |
| { |
| int mx, my, x1, y1; |
| int[] tmp = null; |
| |
| if (nPoints <= 0) { |
| return; |
| } |
| mx = x1 = xPoints[off] + transx; |
| my = y1 = yPoints[off] + transy; |
| while (--nPoints > 0) { |
| ++off; |
| int x2 = xPoints[off] + transx; |
| int y2 = yPoints[off] + transy; |
| tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip, |
| x1, y1, x2, y2); |
| x1 = x2; |
| y1 = y2; |
| } |
| if (close && (x1 != mx || y1 != my)) { |
| tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip, |
| x1, y1, mx, my); |
| } |
| } |
| |
| static void doSetRect(SurfaceData sData, PixelWriter pw, |
| int x1, int y1, int x2, int y2) { |
| WritableRaster dstRast = |
| (WritableRaster) sData.getRaster(x1, y1, x2-x1, y2-y1); |
| pw.setRaster(dstRast); |
| |
| while (y1 < y2) { |
| for (int x = x1; x < x2; x++) { |
| pw.writePixel(x, y1); |
| } |
| y1++; |
| } |
| } |
| |
| static int[] doDrawLine(SurfaceData sData, PixelWriter pw, int[] boundPts, |
| Region clip, |
| int origx1, int origy1, int origx2, int origy2) |
| { |
| if (boundPts == null) { |
| boundPts = new int[8]; |
| } |
| boundPts[0] = origx1; |
| boundPts[1] = origy1; |
| boundPts[2] = origx2; |
| boundPts[3] = origy2; |
| if (!adjustLine(boundPts, |
| clip.getLoX(), clip.getLoY(), |
| clip.getHiX(), clip.getHiY())) |
| { |
| return boundPts; |
| } |
| int x1 = boundPts[0]; |
| int y1 = boundPts[1]; |
| int x2 = boundPts[2]; |
| int y2 = boundPts[3]; |
| |
| WritableRaster dstRast = (WritableRaster) |
| sData.getRaster(Math.min(x1, x2), Math.min(y1, y2), |
| Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1); |
| pw.setRaster(dstRast); |
| |
| /* this could be made smaller, more elegant, more traditional. */ |
| if (x1 == x2) { |
| if (y1 > y2) { |
| do { |
| pw.writePixel(x1, y1); |
| y1--; |
| } while (y1 >= y2); |
| } else { |
| do { |
| pw.writePixel(x1, y1); |
| y1++; |
| } while (y1 <= y2); |
| } |
| } else if (y1 == y2) { |
| if (x1 > x2) { |
| do { |
| pw.writePixel(x1, y1); |
| x1--; |
| } while (x1 >= x2); |
| } else { |
| do { |
| pw.writePixel(x1, y1); |
| x1++; |
| } while (x1 <= x2); |
| } |
| } else { |
| int dx = boundPts[4]; |
| int dy = boundPts[5]; |
| int ax = boundPts[6]; |
| int ay = boundPts[7]; |
| int steps; |
| int bumpmajor; |
| int bumpminor; |
| int errminor; |
| int errmajor; |
| int error; |
| boolean xmajor; |
| |
| if (ax >= ay) { |
| /* x is dominant */ |
| xmajor = true; |
| errmajor = ay * 2; |
| errminor = ax * 2; |
| bumpmajor = (dx < 0) ? -1 : 1; |
| bumpminor = (dy < 0) ? -1 : 1; |
| ax = -ax; /* For clipping adjustment below */ |
| steps = x2 - x1; |
| } else { |
| /* y is dominant */ |
| xmajor = false; |
| errmajor = ax * 2; |
| errminor = ay * 2; |
| bumpmajor = (dy < 0) ? -1 : 1; |
| bumpminor = (dx < 0) ? -1 : 1; |
| ay = -ay; /* For clipping adjustment below */ |
| steps = y2 - y1; |
| } |
| error = - (errminor / 2); |
| if (y1 != origy1) { |
| int ysteps = y1 - origy1; |
| if (ysteps < 0) { |
| ysteps = -ysteps; |
| } |
| error += ysteps * ax * 2; |
| } |
| if (x1 != origx1) { |
| int xsteps = x1 - origx1; |
| if (xsteps < 0) { |
| xsteps = -xsteps; |
| } |
| error += xsteps * ay * 2; |
| } |
| if (steps < 0) { |
| steps = -steps; |
| } |
| if (xmajor) { |
| do { |
| pw.writePixel(x1, y1); |
| x1 += bumpmajor; |
| error += errmajor; |
| if (error >= 0) { |
| y1 += bumpminor; |
| error -= errminor; |
| } |
| } while (--steps >= 0); |
| } else { |
| do { |
| pw.writePixel(x1, y1); |
| y1 += bumpmajor; |
| error += errmajor; |
| if (error >= 0) { |
| x1 += bumpminor; |
| error -= errminor; |
| } |
| } while (--steps >= 0); |
| } |
| } |
| return boundPts; |
| } |
| |
| public static void doDrawRect(PixelWriter pw, |
| SunGraphics2D sg2d, SurfaceData sData, |
| int x, int y, int w, int h) |
| { |
| if (w < 0 || h < 0) { |
| return; |
| } |
| int x2 = Region.dimAdd(Region.dimAdd(x, w), 1); |
| int y2 = Region.dimAdd(Region.dimAdd(y, h), 1); |
| Region r = sg2d.getCompClip().getBoundsIntersectionXYXY(x, y, x2, y2); |
| if (r.isEmpty()) { |
| return; |
| } |
| int cx1 = r.getLoX(); |
| int cy1 = r.getLoY(); |
| int cx2 = r.getHiX(); |
| int cy2 = r.getHiY(); |
| |
| if (w < 2 || h < 2) { |
| doSetRect(sData, pw, cx1, cy1, cx2, cy2); |
| return; |
| } |
| |
| |
| if (cy1 == y) { |
| doSetRect(sData, pw, cx1, cy1, cx2, cy1+1); |
| } |
| if (cx1 == x) { |
| doSetRect(sData, pw, cx1, cy1+1, cx1+1, cy2-1); |
| } |
| if (cx2 == x2) { |
| doSetRect(sData, pw, cx2-1, cy1+1, cx2, cy2-1); |
| } |
| if (cy2 == y2) { |
| doSetRect(sData, pw, cx1, cy2-1, cx2, cy2); |
| } |
| } |
| |
| /* |
| * REMIND: For now this will field both AA and non-AA requests and |
| * use a simple threshold to choose pixels if the supplied grey |
| * bits are antialiased. We should really find a way to disable |
| * AA text at a higher level or to have the GlyphList be able to |
| * reset the glyphs to non-AA after construction. |
| */ |
| static void doDrawGlyphList(SurfaceData sData, PixelWriter pw, |
| GlyphList gl, Region clip) |
| { |
| int[] bounds = gl.getBounds(); |
| clip.clipBoxToBounds(bounds); |
| int cx1 = bounds[0]; |
| int cy1 = bounds[1]; |
| int cx2 = bounds[2]; |
| int cy2 = bounds[3]; |
| |
| WritableRaster dstRast = |
| (WritableRaster) sData.getRaster(cx1, cy1, cx2 - cx1, cy2 - cy1); |
| pw.setRaster(dstRast); |
| |
| int num = gl.getNumGlyphs(); |
| for (int i = 0; i < num; i++) { |
| gl.setGlyphIndex(i); |
| int metrics[] = gl.getMetrics(); |
| int gx1 = metrics[0]; |
| int gy1 = metrics[1]; |
| int w = metrics[2]; |
| int gx2 = gx1 + w; |
| int gy2 = gy1 + metrics[3]; |
| int off = 0; |
| if (gx1 < cx1) { |
| off = cx1 - gx1; |
| gx1 = cx1; |
| } |
| if (gy1 < cy1) { |
| off += (cy1 - gy1) * w; |
| gy1 = cy1; |
| } |
| if (gx2 > cx2) gx2 = cx2; |
| if (gy2 > cy2) gy2 = cy2; |
| if (gx2 > gx1 && gy2 > gy1) { |
| byte alpha[] = gl.getGrayBits(); |
| w -= (gx2 - gx1); |
| for (int y = gy1; y < gy2; y++) { |
| for (int x = gx1; x < gx2; x++) { |
| if (alpha[off++] < 0) { |
| pw.writePixel(x, y); |
| } |
| } |
| off += w; |
| } |
| } |
| } |
| } |
| |
| static final int OUTCODE_TOP = 1; |
| static final int OUTCODE_BOTTOM = 2; |
| static final int OUTCODE_LEFT = 4; |
| static final int OUTCODE_RIGHT = 8; |
| |
| static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) { |
| int code; |
| if (y < ymin) { |
| code = OUTCODE_TOP; |
| } else if (y > ymax) { |
| code = OUTCODE_BOTTOM; |
| } else { |
| code = 0; |
| } |
| if (x < xmin) { |
| code |= OUTCODE_LEFT; |
| } else if (x > xmax) { |
| code |= OUTCODE_RIGHT; |
| } |
| return code; |
| } |
| |
| public static boolean adjustLine(int [] boundPts, |
| int cxmin, int cymin, int cx2, int cy2) |
| { |
| int cxmax = cx2 - 1; |
| int cymax = cy2 - 1; |
| int x1 = boundPts[0]; |
| int y1 = boundPts[1]; |
| int x2 = boundPts[2]; |
| int y2 = boundPts[3]; |
| |
| if ((cxmax < cxmin) || (cymax < cymin)) { |
| return false; |
| } |
| |
| if (x1 == x2) { |
| if (x1 < cxmin || x1 > cxmax) { |
| return false; |
| } |
| if (y1 > y2) { |
| int t = y1; |
| y1 = y2; |
| y2 = t; |
| } |
| if (y1 < cymin) { |
| y1 = cymin; |
| } |
| if (y2 > cymax) { |
| y2 = cymax; |
| } |
| if (y1 > y2) { |
| return false; |
| } |
| boundPts[1] = y1; |
| boundPts[3] = y2; |
| } else if (y1 == y2) { |
| if (y1 < cymin || y1 > cymax) { |
| return false; |
| } |
| if (x1 > x2) { |
| int t = x1; |
| x1 = x2; |
| x2 = t; |
| } |
| if (x1 < cxmin) { |
| x1 = cxmin; |
| } |
| if (x2 > cxmax) { |
| x2 = cxmax; |
| } |
| if (x1 > x2) { |
| return false; |
| } |
| boundPts[0] = x1; |
| boundPts[2] = x2; |
| } else { |
| /* REMIND: This could overflow... */ |
| int outcode1, outcode2; |
| int dx = x2 - x1; |
| int dy = y2 - y1; |
| int ax = (dx < 0) ? -dx : dx; |
| int ay = (dy < 0) ? -dy : dy; |
| boolean xmajor = (ax >= ay); |
| |
| outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); |
| outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); |
| while ((outcode1 | outcode2) != 0) { |
| int xsteps, ysteps; |
| if ((outcode1 & outcode2) != 0) { |
| return false; |
| } |
| if (outcode1 != 0) { |
| if (0 != (outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM))) { |
| if (0 != (outcode1 & OUTCODE_TOP)) { |
| y1 = cymin; |
| } else { |
| y1 = cymax; |
| } |
| ysteps = y1 - boundPts[1]; |
| if (ysteps < 0) { |
| ysteps = -ysteps; |
| } |
| xsteps = 2 * ysteps * ax + ay; |
| if (xmajor) { |
| xsteps += ay - ax - 1; |
| } |
| xsteps = xsteps / (2 * ay); |
| if (dx < 0) { |
| xsteps = -xsteps; |
| } |
| x1 = boundPts[0] + xsteps; |
| } else if (0 != |
| (outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT))) { |
| if (0 != (outcode1 & OUTCODE_LEFT)) { |
| x1 = cxmin; |
| } else { |
| x1 = cxmax; |
| } |
| xsteps = x1 - boundPts[0]; |
| if (xsteps < 0) { |
| xsteps = -xsteps; |
| } |
| ysteps = 2 * xsteps * ay + ax; |
| if (!xmajor) { |
| ysteps += ax - ay - 1; |
| } |
| ysteps = ysteps / (2 * ax); |
| if (dy < 0) { |
| ysteps = -ysteps; |
| } |
| y1 = boundPts[1] + ysteps; |
| } |
| outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); |
| } else { |
| if (0 != (outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM))) { |
| if (0 != (outcode2 & OUTCODE_TOP)) { |
| y2 = cymin; |
| } else { |
| y2 = cymax; |
| } |
| ysteps = y2 - boundPts[3]; |
| if (ysteps < 0) { |
| ysteps = -ysteps; |
| } |
| xsteps = 2 * ysteps * ax + ay; |
| if (xmajor) { |
| xsteps += ay - ax; |
| } else { |
| xsteps -= 1; |
| } |
| xsteps = xsteps / (2 * ay); |
| if (dx > 0) { |
| xsteps = -xsteps; |
| } |
| x2 = boundPts[2] + xsteps; |
| } else if (0 != |
| (outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT))) { |
| if (0 != (outcode2 & OUTCODE_LEFT)) { |
| x2 = cxmin; |
| } else { |
| x2 = cxmax; |
| } |
| xsteps = x2 - boundPts[2]; |
| if (xsteps < 0) { |
| xsteps = -xsteps; |
| } |
| ysteps = 2 * xsteps * ay + ax; |
| if (xmajor) { |
| ysteps -= 1; |
| } else { |
| ysteps += ax - ay; |
| } |
| ysteps = ysteps / (2 * ax); |
| if (dy > 0) { |
| ysteps = -ysteps; |
| } |
| y2 = boundPts[3] + ysteps; |
| } |
| outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); |
| } |
| } |
| boundPts[0] = x1; |
| boundPts[1] = y1; |
| boundPts[2] = x2; |
| boundPts[3] = y2; |
| boundPts[4] = dx; |
| boundPts[5] = dy; |
| boundPts[6] = ax; |
| boundPts[7] = ay; |
| } |
| return true; |
| } |
| |
| static PixelWriter createSolidPixelWriter(SunGraphics2D sg2d, |
| SurfaceData sData) |
| { |
| ColorModel dstCM = sData.getColorModel(); |
| Object srcPixel = dstCM.getDataElements(sg2d.eargb, null); |
| |
| return new SolidPixelWriter(srcPixel); |
| } |
| |
| static PixelWriter createXorPixelWriter(SunGraphics2D sg2d, |
| SurfaceData sData) |
| { |
| ColorModel dstCM = sData.getColorModel(); |
| |
| Object srcPixel = dstCM.getDataElements(sg2d.eargb, null); |
| |
| XORComposite comp = (XORComposite)sg2d.getComposite(); |
| int xorrgb = comp.getXorColor().getRGB(); |
| Object xorPixel = dstCM.getDataElements(xorrgb, null); |
| |
| switch (dstCM.getTransferType()) { |
| case DataBuffer.TYPE_BYTE: |
| return new XorPixelWriter.ByteData(srcPixel, xorPixel); |
| case DataBuffer.TYPE_SHORT: |
| case DataBuffer.TYPE_USHORT: |
| return new XorPixelWriter.ShortData(srcPixel, xorPixel); |
| case DataBuffer.TYPE_INT: |
| return new XorPixelWriter.IntData(srcPixel, xorPixel); |
| case DataBuffer.TYPE_FLOAT: |
| return new XorPixelWriter.FloatData(srcPixel, xorPixel); |
| case DataBuffer.TYPE_DOUBLE: |
| return new XorPixelWriter.DoubleData(srcPixel, xorPixel); |
| default: |
| throw new InternalError("Unsupported XOR pixel type"); |
| } |
| } |
| } |
| |
| class SetFillRectANY extends FillRect { |
| SetFillRectANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void FillRect(SunGraphics2D sg2d, SurfaceData sData, |
| int x, int y, int w, int h) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| |
| Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h); |
| |
| GeneralRenderer.doSetRect(sData, pw, |
| r.getLoX(), r.getLoY(), |
| r.getHiX(), r.getHiY()); |
| } |
| } |
| |
| class PixelWriterDrawHandler extends ProcessPath.DrawHandler { |
| PixelWriter pw; |
| SurfaceData sData; |
| Region clip; |
| |
| public PixelWriterDrawHandler(SurfaceData sData, PixelWriter pw, |
| Region clip, int strokeHint) { |
| super(clip.getLoX(), clip.getLoY(), |
| clip.getHiX(), clip.getHiY(), |
| strokeHint); |
| this.sData = sData; |
| this.pw = pw; |
| this.clip = clip; |
| } |
| |
| public void drawLine(int x0, int y0, int x1, int y1) { |
| GeneralRenderer.doDrawLine(sData, pw, null, clip, |
| x0, y0, x1, y1); |
| } |
| |
| public void drawPixel(int x0, int y0) { |
| GeneralRenderer.doSetRect(sData, pw, x0, y0, x0 + 1, y0 + 1); |
| } |
| |
| public void drawScanline(int x0, int x1, int y0) { |
| GeneralRenderer.doSetRect(sData, pw, x0, y0, x1 + 1, y0 + 1); |
| } |
| } |
| |
| class SetFillPathANY extends FillPath { |
| SetFillPathANY() { |
| super(SurfaceType.AnyColor, CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void FillPath(SunGraphics2D sg2d, SurfaceData sData, |
| int transx, int transy, |
| Path2D.Float p2df) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| ProcessPath.fillPath( |
| new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), |
| sg2d.strokeHint), |
| p2df, transx, transy); |
| } |
| } |
| |
| class SetFillSpansANY extends FillSpans { |
| SetFillSpansANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void FillSpans(SunGraphics2D sg2d, SurfaceData sData, |
| SpanIterator si) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| |
| int span[] = new int[4]; |
| while (si.nextSpan(span)) { |
| GeneralRenderer.doSetRect(sData, pw, |
| span[0], span[1], span[2], span[3]); |
| } |
| } |
| } |
| |
| class SetDrawLineANY extends DrawLine { |
| SetDrawLineANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void DrawLine(SunGraphics2D sg2d, SurfaceData sData, |
| int x1, int y1, int x2, int y2) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| |
| if (y1 >= y2) { |
| GeneralRenderer.doDrawLine(sData, pw, null, |
| sg2d.getCompClip(), |
| x2, y2, x1, y1); |
| } else { |
| GeneralRenderer.doDrawLine(sData, pw, null, |
| sg2d.getCompClip(), |
| x1, y1, x2, y2); |
| } |
| } |
| } |
| |
| class SetDrawPolygonsANY extends DrawPolygons { |
| SetDrawPolygonsANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData, |
| int xPoints[], int yPoints[], |
| int nPoints[], int numPolys, |
| int transx, int transy, |
| boolean close) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| |
| int off = 0; |
| Region clip = sg2d.getCompClip(); |
| for (int i = 0; i < numPolys; i++) { |
| int numpts = nPoints[i]; |
| GeneralRenderer.doDrawPoly(sData, pw, |
| xPoints, yPoints, off, numpts, |
| clip, transx, transy, close); |
| off += numpts; |
| } |
| } |
| } |
| |
| class SetDrawPathANY extends DrawPath { |
| SetDrawPathANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void DrawPath(SunGraphics2D sg2d, SurfaceData sData, |
| int transx, int transy, |
| Path2D.Float p2df) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| ProcessPath.drawPath( |
| new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), |
| sg2d.strokeHint), |
| p2df, transx, transy |
| ); |
| } |
| } |
| |
| class SetDrawRectANY extends DrawRect { |
| SetDrawRectANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.SrcNoEa, |
| SurfaceType.Any); |
| } |
| |
| public void DrawRect(SunGraphics2D sg2d, SurfaceData sData, |
| int x, int y, int w, int h) |
| { |
| PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); |
| |
| GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h); |
| } |
| } |
| |
| class XorFillRectANY extends FillRect { |
| XorFillRectANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void FillRect(SunGraphics2D sg2d, SurfaceData sData, |
| int x, int y, int w, int h) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| |
| Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h); |
| |
| GeneralRenderer.doSetRect(sData, pw, |
| r.getLoX(), r.getLoY(), |
| r.getHiX(), r.getHiY()); |
| } |
| } |
| |
| class XorFillPathANY extends FillPath { |
| XorFillPathANY() { |
| super(SurfaceType.AnyColor, CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void FillPath(SunGraphics2D sg2d, SurfaceData sData, |
| int transx, int transy, |
| Path2D.Float p2df) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| ProcessPath.fillPath( |
| new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), |
| sg2d.strokeHint), |
| p2df, transx, transy); |
| } |
| } |
| |
| class XorFillSpansANY extends FillSpans { |
| XorFillSpansANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void FillSpans(SunGraphics2D sg2d, SurfaceData sData, |
| SpanIterator si) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| |
| int span[] = new int[4]; |
| while (si.nextSpan(span)) { |
| GeneralRenderer.doSetRect(sData, pw, |
| span[0], span[1], span[2], span[3]); |
| } |
| } |
| } |
| |
| class XorDrawLineANY extends DrawLine { |
| XorDrawLineANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void DrawLine(SunGraphics2D sg2d, SurfaceData sData, |
| int x1, int y1, int x2, int y2) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| |
| if (y1 >= y2) { |
| GeneralRenderer.doDrawLine(sData, pw, null, |
| sg2d.getCompClip(), |
| x2, y2, x1, y1); |
| } else { |
| GeneralRenderer.doDrawLine(sData, pw, null, |
| sg2d.getCompClip(), |
| x1, y1, x2, y2); |
| } |
| } |
| } |
| |
| class XorDrawPolygonsANY extends DrawPolygons { |
| XorDrawPolygonsANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData, |
| int xPoints[], int yPoints[], |
| int nPoints[], int numPolys, |
| int transx, int transy, |
| boolean close) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| |
| int off = 0; |
| Region clip = sg2d.getCompClip(); |
| for (int i = 0; i < numPolys; i++) { |
| int numpts = nPoints[i]; |
| GeneralRenderer.doDrawPoly(sData, pw, |
| xPoints, yPoints, off, numpts, |
| clip, transx, transy, close); |
| off += numpts; |
| } |
| } |
| } |
| |
| class XorDrawPathANY extends DrawPath { |
| XorDrawPathANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void DrawPath(SunGraphics2D sg2d, SurfaceData sData, |
| int transx, int transy, Path2D.Float p2df) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| ProcessPath.drawPath( |
| new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), |
| sg2d.strokeHint), |
| p2df, transx, transy |
| ); |
| } |
| } |
| |
| class XorDrawRectANY extends DrawRect { |
| XorDrawRectANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void DrawRect(SunGraphics2D sg2d, SurfaceData sData, |
| int x, int y, int w, int h) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| |
| GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h); |
| } |
| } |
| |
| class XorDrawGlyphListANY extends DrawGlyphList { |
| XorDrawGlyphListANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData sData, |
| GlyphList gl) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip()); |
| } |
| } |
| |
| class XorDrawGlyphListAAANY extends DrawGlyphListAA { |
| XorDrawGlyphListAAANY() { |
| super(SurfaceType.AnyColor, |
| CompositeType.Xor, |
| SurfaceType.Any); |
| } |
| |
| public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData sData, |
| GlyphList gl) |
| { |
| PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); |
| GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip()); |
| } |
| } |
| |
| abstract class PixelWriter { |
| protected WritableRaster dstRast; |
| |
| public void setRaster(WritableRaster dstRast) { |
| this.dstRast = dstRast; |
| } |
| |
| public abstract void writePixel(int x, int y); |
| } |
| |
| class SolidPixelWriter extends PixelWriter { |
| protected Object srcData; |
| |
| SolidPixelWriter(Object srcPixel) { |
| this.srcData = srcPixel; |
| } |
| |
| public void writePixel(int x, int y) { |
| dstRast.setDataElements(x, y, srcData); |
| } |
| } |
| |
| abstract class XorPixelWriter extends PixelWriter { |
| protected ColorModel dstCM; |
| |
| public void writePixel(int x, int y) { |
| Object dstPixel = dstRast.getDataElements(x, y, null); |
| xorPixel(dstPixel); |
| dstRast.setDataElements(x, y, dstPixel); |
| } |
| |
| protected abstract void xorPixel(Object pixData); |
| |
| public static class ByteData extends XorPixelWriter { |
| byte[] xorData; |
| |
| ByteData(Object srcPixel, Object xorPixel) { |
| this.xorData = (byte[]) srcPixel; |
| xorPixel(xorPixel); |
| this.xorData = (byte[]) xorPixel; |
| } |
| |
| protected void xorPixel(Object pixData) { |
| byte[] dstData = (byte[]) pixData; |
| for (int i = 0; i < dstData.length; i++) { |
| dstData[i] ^= xorData[i]; |
| } |
| } |
| } |
| |
| public static class ShortData extends XorPixelWriter { |
| short[] xorData; |
| |
| ShortData(Object srcPixel, Object xorPixel) { |
| this.xorData = (short[]) srcPixel; |
| xorPixel(xorPixel); |
| this.xorData = (short[]) xorPixel; |
| } |
| |
| protected void xorPixel(Object pixData) { |
| short[] dstData = (short[]) pixData; |
| for (int i = 0; i < dstData.length; i++) { |
| dstData[i] ^= xorData[i]; |
| } |
| } |
| } |
| |
| public static class IntData extends XorPixelWriter { |
| int[] xorData; |
| |
| IntData(Object srcPixel, Object xorPixel) { |
| this.xorData = (int[]) srcPixel; |
| xorPixel(xorPixel); |
| this.xorData = (int[]) xorPixel; |
| } |
| |
| protected void xorPixel(Object pixData) { |
| int[] dstData = (int[]) pixData; |
| for (int i = 0; i < dstData.length; i++) { |
| dstData[i] ^= xorData[i]; |
| } |
| } |
| } |
| |
| public static class FloatData extends XorPixelWriter { |
| int[] xorData; |
| |
| FloatData(Object srcPixel, Object xorPixel) { |
| float[] srcData = (float[]) srcPixel; |
| float[] xorData = (float[]) xorPixel; |
| this.xorData = new int[srcData.length]; |
| for (int i = 0; i < srcData.length; i++) { |
| this.xorData[i] = (Float.floatToIntBits(srcData[i]) ^ |
| Float.floatToIntBits(xorData[i])); |
| } |
| } |
| |
| protected void xorPixel(Object pixData) { |
| float[] dstData = (float[]) pixData; |
| for (int i = 0; i < dstData.length; i++) { |
| int v = Float.floatToIntBits(dstData[i]) ^ xorData[i]; |
| dstData[i] = Float.intBitsToFloat(v); |
| } |
| } |
| } |
| |
| public static class DoubleData extends XorPixelWriter { |
| long[] xorData; |
| |
| DoubleData(Object srcPixel, Object xorPixel) { |
| double[] srcData = (double[]) srcPixel; |
| double[] xorData = (double[]) xorPixel; |
| this.xorData = new long[srcData.length]; |
| for (int i = 0; i < srcData.length; i++) { |
| this.xorData[i] = (Double.doubleToLongBits(srcData[i]) ^ |
| Double.doubleToLongBits(xorData[i])); |
| } |
| } |
| |
| protected void xorPixel(Object pixData) { |
| double[] dstData = (double[]) pixData; |
| for (int i = 0; i < dstData.length; i++) { |
| long v = Double.doubleToLongBits(dstData[i]) ^ xorData[i]; |
| dstData[i] = Double.longBitsToDouble(v); |
| } |
| } |
| } |
| } |