0001: /*
0002: * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: /*
0027: * @author Charlton Innovations, Inc.
0028: */
0029:
0030: package sun.java2d.loops;
0031:
0032: import java.awt.image.WritableRaster;
0033: import java.awt.image.DataBuffer;
0034: import java.awt.image.ColorModel;
0035: import java.awt.geom.Path2D;
0036: import java.awt.geom.PathIterator;
0037: import java.awt.geom.AffineTransform;
0038: import sun.java2d.pipe.Region;
0039: import sun.java2d.pipe.SpanIterator;
0040: import sun.java2d.SunGraphics2D;
0041: import sun.java2d.SurfaceData;
0042: import sun.java2d.loops.ProcessPath;
0043: import sun.font.GlyphList;
0044:
0045: /**
0046: * GeneralRenderer collection
0047: * Basically, a collection of components which permit basic
0048: * rendering to occur on rasters of any format
0049: */
0050:
0051: public final class GeneralRenderer {
0052: public static void register() {
0053: Class owner = GeneralRenderer.class;
0054: GraphicsPrimitive[] primitives = {
0055: new GraphicsPrimitiveProxy(owner, "SetFillRectANY",
0056: FillRect.methodSignature, FillRect.primTypeID,
0057: SurfaceType.AnyColor, CompositeType.SrcNoEa,
0058: SurfaceType.Any),
0059: new GraphicsPrimitiveProxy(owner, "SetFillPathANY",
0060: FillPath.methodSignature, FillPath.primTypeID,
0061: SurfaceType.AnyColor, CompositeType.SrcNoEa,
0062: SurfaceType.Any),
0063: new GraphicsPrimitiveProxy(owner, "SetFillSpansANY",
0064: FillSpans.methodSignature,
0065: FillSpans.primTypeID, SurfaceType.AnyColor,
0066: CompositeType.SrcNoEa, SurfaceType.Any),
0067: new GraphicsPrimitiveProxy(owner, "SetDrawLineANY",
0068: DrawLine.methodSignature, DrawLine.primTypeID,
0069: SurfaceType.AnyColor, CompositeType.SrcNoEa,
0070: SurfaceType.Any),
0071: new GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY",
0072: DrawPolygons.methodSignature,
0073: DrawPolygons.primTypeID, SurfaceType.AnyColor,
0074: CompositeType.SrcNoEa, SurfaceType.Any),
0075: new GraphicsPrimitiveProxy(owner, "SetDrawPathANY",
0076: DrawPath.methodSignature, DrawPath.primTypeID,
0077: SurfaceType.AnyColor, CompositeType.SrcNoEa,
0078: SurfaceType.Any),
0079: new GraphicsPrimitiveProxy(owner, "SetDrawRectANY",
0080: DrawRect.methodSignature, DrawRect.primTypeID,
0081: SurfaceType.AnyColor, CompositeType.SrcNoEa,
0082: SurfaceType.Any),
0083:
0084: new GraphicsPrimitiveProxy(owner, "XorFillRectANY",
0085: FillRect.methodSignature, FillRect.primTypeID,
0086: SurfaceType.AnyColor, CompositeType.Xor,
0087: SurfaceType.Any),
0088: new GraphicsPrimitiveProxy(owner, "XorFillPathANY",
0089: FillPath.methodSignature, FillPath.primTypeID,
0090: SurfaceType.AnyColor, CompositeType.Xor,
0091: SurfaceType.Any),
0092: new GraphicsPrimitiveProxy(owner, "XorFillSpansANY",
0093: FillSpans.methodSignature,
0094: FillSpans.primTypeID, SurfaceType.AnyColor,
0095: CompositeType.Xor, SurfaceType.Any),
0096: new GraphicsPrimitiveProxy(owner, "XorDrawLineANY",
0097: DrawLine.methodSignature, DrawLine.primTypeID,
0098: SurfaceType.AnyColor, CompositeType.Xor,
0099: SurfaceType.Any),
0100: new GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY",
0101: DrawPolygons.methodSignature,
0102: DrawPolygons.primTypeID, SurfaceType.AnyColor,
0103: CompositeType.Xor, SurfaceType.Any),
0104: new GraphicsPrimitiveProxy(owner, "XorDrawPathANY",
0105: DrawPath.methodSignature, DrawPath.primTypeID,
0106: SurfaceType.AnyColor, CompositeType.Xor,
0107: SurfaceType.Any),
0108: new GraphicsPrimitiveProxy(owner, "XorDrawRectANY",
0109: DrawRect.methodSignature, DrawRect.primTypeID,
0110: SurfaceType.AnyColor, CompositeType.Xor,
0111: SurfaceType.Any),
0112: new GraphicsPrimitiveProxy(owner,
0113: "XorDrawGlyphListANY",
0114: DrawGlyphList.methodSignature,
0115: DrawGlyphList.primTypeID, SurfaceType.AnyColor,
0116: CompositeType.Xor, SurfaceType.Any),
0117: new GraphicsPrimitiveProxy(owner,
0118: "XorDrawGlyphListAAANY",
0119: DrawGlyphListAA.methodSignature,
0120: DrawGlyphListAA.primTypeID,
0121: SurfaceType.AnyColor, CompositeType.Xor,
0122: SurfaceType.Any), };
0123: GraphicsPrimitiveMgr.register(primitives);
0124: }
0125:
0126: static void doDrawPoly(SurfaceData sData, PixelWriter pw,
0127: int xPoints[], int yPoints[], int off, int nPoints,
0128: Region clip, int transx, int transy, boolean close) {
0129: int mx, my, x1, y1;
0130: int[] tmp = null;
0131: mx = x1 = xPoints[off] + transx;
0132: my = y1 = yPoints[off] + transy;
0133: while (--nPoints > 0) {
0134: ++off;
0135: int x2 = xPoints[off] + transx;
0136: int y2 = yPoints[off] + transy;
0137: tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip, x1,
0138: y1, x2, y2);
0139: x1 = x2;
0140: y1 = y2;
0141: }
0142: if (close && (x1 != mx || y1 != my)) {
0143: tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip, x1,
0144: y1, mx, my);
0145: }
0146: }
0147:
0148: static void doSetRect(SurfaceData sData, PixelWriter pw, int x1,
0149: int y1, int x2, int y2) {
0150: WritableRaster dstRast = (WritableRaster) sData.getRaster(x1,
0151: y1, x2 - x1, y2 - y1);
0152: pw.setRaster(dstRast);
0153:
0154: while (y1 < y2) {
0155: for (int x = x1; x < x2; x++) {
0156: pw.writePixel(x, y1);
0157: }
0158: y1++;
0159: }
0160: }
0161:
0162: static int[] doDrawLine(SurfaceData sData, PixelWriter pw,
0163: int[] boundPts, Region clip, int origx1, int origy1,
0164: int origx2, int origy2) {
0165: if (boundPts == null) {
0166: boundPts = new int[8];
0167: }
0168: boundPts[0] = origx1;
0169: boundPts[1] = origy1;
0170: boundPts[2] = origx2;
0171: boundPts[3] = origy2;
0172: if (!adjustLine(boundPts, clip.getLoX(), clip.getLoY(), clip
0173: .getHiX(), clip.getHiY())) {
0174: return boundPts;
0175: }
0176: int x1 = boundPts[0];
0177: int y1 = boundPts[1];
0178: int x2 = boundPts[2];
0179: int y2 = boundPts[3];
0180:
0181: WritableRaster dstRast = (WritableRaster) sData.getRaster(Math
0182: .min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2) + 1,
0183: Math.abs(y1 - y2) + 1);
0184: pw.setRaster(dstRast);
0185:
0186: /* this could be made smaller, more elegant, more traditional. */
0187: if (x1 == x2) {
0188: if (y1 > y2) {
0189: do {
0190: pw.writePixel(x1, y1);
0191: y1--;
0192: } while (y1 >= y2);
0193: } else {
0194: do {
0195: pw.writePixel(x1, y1);
0196: y1++;
0197: } while (y1 <= y2);
0198: }
0199: } else if (y1 == y2) {
0200: if (x1 > x2) {
0201: do {
0202: pw.writePixel(x1, y1);
0203: x1--;
0204: } while (x1 >= x2);
0205: } else {
0206: do {
0207: pw.writePixel(x1, y1);
0208: x1++;
0209: } while (x1 <= x2);
0210: }
0211: } else {
0212: int dx = boundPts[4];
0213: int dy = boundPts[5];
0214: int ax = boundPts[6];
0215: int ay = boundPts[7];
0216: int steps;
0217: int bumpmajor;
0218: int bumpminor;
0219: int errminor;
0220: int errmajor;
0221: int error;
0222: boolean xmajor;
0223:
0224: if (ax >= ay) {
0225: /* x is dominant */
0226: xmajor = true;
0227: errmajor = ay * 2;
0228: errminor = ax * 2;
0229: bumpmajor = (dx < 0) ? -1 : 1;
0230: bumpminor = (dy < 0) ? -1 : 1;
0231: ax = -ax; /* For clipping adjustment below */
0232: steps = x2 - x1;
0233: } else {
0234: /* y is dominant */
0235: xmajor = false;
0236: errmajor = ax * 2;
0237: errminor = ay * 2;
0238: bumpmajor = (dy < 0) ? -1 : 1;
0239: bumpminor = (dx < 0) ? -1 : 1;
0240: ay = -ay; /* For clipping adjustment below */
0241: steps = y2 - y1;
0242: }
0243: error = -(errminor / 2);
0244: if (y1 != origy1) {
0245: int ysteps = y1 - origy1;
0246: if (ysteps < 0) {
0247: ysteps = -ysteps;
0248: }
0249: error += ysteps * ax * 2;
0250: }
0251: if (x1 != origx1) {
0252: int xsteps = x1 - origx1;
0253: if (xsteps < 0) {
0254: xsteps = -xsteps;
0255: }
0256: error += xsteps * ay * 2;
0257: }
0258: if (steps < 0) {
0259: steps = -steps;
0260: }
0261: if (xmajor) {
0262: do {
0263: pw.writePixel(x1, y1);
0264: x1 += bumpmajor;
0265: error += errmajor;
0266: if (error >= 0) {
0267: y1 += bumpminor;
0268: error -= errminor;
0269: }
0270: } while (--steps >= 0);
0271: } else {
0272: do {
0273: pw.writePixel(x1, y1);
0274: y1 += bumpmajor;
0275: error += errmajor;
0276: if (error >= 0) {
0277: x1 += bumpminor;
0278: error -= errminor;
0279: }
0280: } while (--steps >= 0);
0281: }
0282: }
0283: return boundPts;
0284: }
0285:
0286: public static void doDrawRect(PixelWriter pw, SunGraphics2D sg2d,
0287: SurfaceData sData, int x, int y, int w, int h) {
0288: if (w < 0 || h < 0) {
0289: return;
0290: }
0291: int x2 = Region.dimAdd(Region.dimAdd(x, w), 1);
0292: int y2 = Region.dimAdd(Region.dimAdd(y, h), 1);
0293: Region r = sg2d.getCompClip().getBoundsIntersectionXYXY(x, y,
0294: x2, y2);
0295: if (r.isEmpty()) {
0296: return;
0297: }
0298: int cx1 = r.getLoX();
0299: int cy1 = r.getLoY();
0300: int cx2 = r.getHiX();
0301: int cy2 = r.getHiY();
0302:
0303: if (w < 2 || h < 2) {
0304: doSetRect(sData, pw, cx1, cy1, cx2, cy2);
0305: return;
0306: }
0307:
0308: if (cy1 == y) {
0309: doSetRect(sData, pw, cx1, cy1, cx2, cy1 + 1);
0310: }
0311: if (cx1 == x) {
0312: doSetRect(sData, pw, cx1, cy1 + 1, cx1 + 1, cy2 - 1);
0313: }
0314: if (cx2 == x2) {
0315: doSetRect(sData, pw, cx2 - 1, cy1 + 1, cx2, cy2 - 1);
0316: }
0317: if (cy2 == y2) {
0318: doSetRect(sData, pw, cx1, cy2 - 1, cx2, cy2);
0319: }
0320: }
0321:
0322: /*
0323: * REMIND: For now this will field both AA and non-AA requests and
0324: * use a simple threshold to choose pixels if the supplied grey
0325: * bits are antialiased. We should really find a way to disable
0326: * AA text at a higher level or to have the GlyphList be able to
0327: * reset the glyphs to non-AA after construction.
0328: */
0329: static void doDrawGlyphList(SurfaceData sData, PixelWriter pw,
0330: GlyphList gl, Region clip) {
0331: int[] bounds = gl.getBounds();
0332: clip.clipBoxToBounds(bounds);
0333: int cx1 = bounds[0];
0334: int cy1 = bounds[1];
0335: int cx2 = bounds[2];
0336: int cy2 = bounds[3];
0337:
0338: WritableRaster dstRast = (WritableRaster) sData.getRaster(cx1,
0339: cy1, cx2 - cx1, cy2 - cy1);
0340: pw.setRaster(dstRast);
0341:
0342: int num = gl.getNumGlyphs();
0343: for (int i = 0; i < num; i++) {
0344: gl.setGlyphIndex(i);
0345: int metrics[] = gl.getMetrics();
0346: int gx1 = metrics[0];
0347: int gy1 = metrics[1];
0348: int w = metrics[2];
0349: int gx2 = gx1 + w;
0350: int gy2 = gy1 + metrics[3];
0351: int off = 0;
0352: if (gx1 < cx1) {
0353: off = cx1 - gx1;
0354: gx1 = cx1;
0355: }
0356: if (gy1 < cy1) {
0357: off += (cy1 - gy1) * w;
0358: gy1 = cy1;
0359: }
0360: if (gx2 > cx2)
0361: gx2 = cx2;
0362: if (gy2 > cy2)
0363: gy2 = cy2;
0364: if (gx2 > gx1 && gy2 > gy1) {
0365: byte alpha[] = gl.getGrayBits();
0366: w -= (gx2 - gx1);
0367: for (int y = gy1; y < gy2; y++) {
0368: for (int x = gx1; x < gx2; x++) {
0369: if (alpha[off++] < 0) {
0370: pw.writePixel(x, y);
0371: }
0372: }
0373: off += w;
0374: }
0375: }
0376: }
0377: }
0378:
0379: static final int OUTCODE_TOP = 1;
0380: static final int OUTCODE_BOTTOM = 2;
0381: static final int OUTCODE_LEFT = 4;
0382: static final int OUTCODE_RIGHT = 8;
0383:
0384: static int outcode(int x, int y, int xmin, int ymin, int xmax,
0385: int ymax) {
0386: int code;
0387: if (y < ymin) {
0388: code = OUTCODE_TOP;
0389: } else if (y > ymax) {
0390: code = OUTCODE_BOTTOM;
0391: } else {
0392: code = 0;
0393: }
0394: if (x < xmin) {
0395: code |= OUTCODE_LEFT;
0396: } else if (x > xmax) {
0397: code |= OUTCODE_RIGHT;
0398: }
0399: return code;
0400: }
0401:
0402: public static boolean adjustLine(int[] boundPts, int cxmin,
0403: int cymin, int cx2, int cy2) {
0404: int cxmax = cx2 - 1;
0405: int cymax = cy2 - 1;
0406: int x1 = boundPts[0];
0407: int y1 = boundPts[1];
0408: int x2 = boundPts[2];
0409: int y2 = boundPts[3];
0410:
0411: if ((cxmax < cxmin) || (cymax < cymin)) {
0412: return false;
0413: }
0414:
0415: if (x1 == x2) {
0416: if (x1 < cxmin || x1 > cxmax) {
0417: return false;
0418: }
0419: if (y1 > y2) {
0420: int t = y1;
0421: y1 = y2;
0422: y2 = t;
0423: }
0424: if (y1 < cymin) {
0425: y1 = cymin;
0426: }
0427: if (y2 > cymax) {
0428: y2 = cymax;
0429: }
0430: if (y1 > y2) {
0431: return false;
0432: }
0433: boundPts[1] = y1;
0434: boundPts[3] = y2;
0435: } else if (y1 == y2) {
0436: if (y1 < cymin || y1 > cymax) {
0437: return false;
0438: }
0439: if (x1 > x2) {
0440: int t = x1;
0441: x1 = x2;
0442: x2 = t;
0443: }
0444: if (x1 < cxmin) {
0445: x1 = cxmin;
0446: }
0447: if (x2 > cxmax) {
0448: x2 = cxmax;
0449: }
0450: if (x1 > x2) {
0451: return false;
0452: }
0453: boundPts[0] = x1;
0454: boundPts[2] = x2;
0455: } else {
0456: /* REMIND: This could overflow... */
0457: int outcode1, outcode2;
0458: int dx = x2 - x1;
0459: int dy = y2 - y1;
0460: int ax = (dx < 0) ? -dx : dx;
0461: int ay = (dy < 0) ? -dy : dy;
0462: boolean xmajor = (ax >= ay);
0463:
0464: outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
0465: outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
0466: while ((outcode1 | outcode2) != 0) {
0467: int xsteps, ysteps;
0468: if ((outcode1 & outcode2) != 0) {
0469: return false;
0470: }
0471: if (outcode1 != 0) {
0472: if (0 != (outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {
0473: if (0 != (outcode1 & OUTCODE_TOP)) {
0474: y1 = cymin;
0475: } else {
0476: y1 = cymax;
0477: }
0478: ysteps = y1 - boundPts[1];
0479: if (ysteps < 0) {
0480: ysteps = -ysteps;
0481: }
0482: xsteps = 2 * ysteps * ax + ay;
0483: if (xmajor) {
0484: xsteps += ay - ax - 1;
0485: }
0486: xsteps = xsteps / (2 * ay);
0487: if (dx < 0) {
0488: xsteps = -xsteps;
0489: }
0490: x1 = boundPts[0] + xsteps;
0491: } else if (0 != (outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {
0492: if (0 != (outcode1 & OUTCODE_LEFT)) {
0493: x1 = cxmin;
0494: } else {
0495: x1 = cxmax;
0496: }
0497: xsteps = x1 - boundPts[0];
0498: if (xsteps < 0) {
0499: xsteps = -xsteps;
0500: }
0501: ysteps = 2 * xsteps * ay + ax;
0502: if (!xmajor) {
0503: ysteps += ax - ay - 1;
0504: }
0505: ysteps = ysteps / (2 * ax);
0506: if (dy < 0) {
0507: ysteps = -ysteps;
0508: }
0509: y1 = boundPts[1] + ysteps;
0510: }
0511: outcode1 = outcode(x1, y1, cxmin, cymin, cxmax,
0512: cymax);
0513: } else {
0514: if (0 != (outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {
0515: if (0 != (outcode2 & OUTCODE_TOP)) {
0516: y2 = cymin;
0517: } else {
0518: y2 = cymax;
0519: }
0520: ysteps = y2 - boundPts[3];
0521: if (ysteps < 0) {
0522: ysteps = -ysteps;
0523: }
0524: xsteps = 2 * ysteps * ax + ay;
0525: if (xmajor) {
0526: xsteps += ay - ax;
0527: } else {
0528: xsteps -= 1;
0529: }
0530: xsteps = xsteps / (2 * ay);
0531: if (dx > 0) {
0532: xsteps = -xsteps;
0533: }
0534: x2 = boundPts[2] + xsteps;
0535: } else if (0 != (outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {
0536: if (0 != (outcode2 & OUTCODE_LEFT)) {
0537: x2 = cxmin;
0538: } else {
0539: x2 = cxmax;
0540: }
0541: xsteps = x2 - boundPts[2];
0542: if (xsteps < 0) {
0543: xsteps = -xsteps;
0544: }
0545: ysteps = 2 * xsteps * ay + ax;
0546: if (xmajor) {
0547: ysteps -= 1;
0548: } else {
0549: ysteps += ax - ay;
0550: }
0551: ysteps = ysteps / (2 * ax);
0552: if (dy > 0) {
0553: ysteps = -ysteps;
0554: }
0555: y2 = boundPts[3] + ysteps;
0556: }
0557: outcode2 = outcode(x2, y2, cxmin, cymin, cxmax,
0558: cymax);
0559: }
0560: }
0561: boundPts[0] = x1;
0562: boundPts[1] = y1;
0563: boundPts[2] = x2;
0564: boundPts[3] = y2;
0565: boundPts[4] = dx;
0566: boundPts[5] = dy;
0567: boundPts[6] = ax;
0568: boundPts[7] = ay;
0569: }
0570: return true;
0571: }
0572:
0573: static PixelWriter createSolidPixelWriter(SunGraphics2D sg2d,
0574: SurfaceData sData) {
0575: ColorModel dstCM = sData.getColorModel();
0576: Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);
0577:
0578: return new SolidPixelWriter(srcPixel);
0579: }
0580:
0581: static PixelWriter createXorPixelWriter(SunGraphics2D sg2d,
0582: SurfaceData sData) {
0583: ColorModel dstCM = sData.getColorModel();
0584:
0585: Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);
0586:
0587: XORComposite comp = (XORComposite) sg2d.getComposite();
0588: int xorrgb = comp.getXorColor().getRGB();
0589: Object xorPixel = dstCM.getDataElements(xorrgb, null);
0590:
0591: switch (dstCM.getTransferType()) {
0592: case DataBuffer.TYPE_BYTE:
0593: return new XorPixelWriter.ByteData(srcPixel, xorPixel);
0594: case DataBuffer.TYPE_SHORT:
0595: case DataBuffer.TYPE_USHORT:
0596: return new XorPixelWriter.ShortData(srcPixel, xorPixel);
0597: case DataBuffer.TYPE_INT:
0598: return new XorPixelWriter.IntData(srcPixel, xorPixel);
0599: case DataBuffer.TYPE_FLOAT:
0600: return new XorPixelWriter.FloatData(srcPixel, xorPixel);
0601: case DataBuffer.TYPE_DOUBLE:
0602: return new XorPixelWriter.DoubleData(srcPixel, xorPixel);
0603: default:
0604: throw new InternalError("Unsupported XOR pixel type");
0605: }
0606: }
0607: }
0608:
0609: class SetFillRectANY extends FillRect {
0610: SetFillRectANY() {
0611: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0612: SurfaceType.Any);
0613: }
0614:
0615: public void FillRect(SunGraphics2D sg2d, SurfaceData sData, int x,
0616: int y, int w, int h) {
0617: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0618: sData);
0619:
0620: Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y,
0621: w, h);
0622:
0623: GeneralRenderer.doSetRect(sData, pw, r.getLoX(), r.getLoY(), r
0624: .getHiX(), r.getHiY());
0625: }
0626: }
0627:
0628: class PixelWriterDrawHandler extends ProcessPath.DrawHandler {
0629: PixelWriter pw;
0630: SurfaceData sData;
0631: Region clip;
0632:
0633: public PixelWriterDrawHandler(SurfaceData sData, PixelWriter pw,
0634: Region clip, int strokeHint) {
0635: super (clip.getLoX(), clip.getLoY(), clip.getHiX(), clip
0636: .getHiY(), strokeHint);
0637: this .sData = sData;
0638: this .pw = pw;
0639: this .clip = clip;
0640: }
0641:
0642: public void drawLine(int x0, int y0, int x1, int y1) {
0643: GeneralRenderer.doDrawLine(sData, pw, null, clip, x0, y0, x1,
0644: y1);
0645: }
0646:
0647: public void drawPixel(int x0, int y0) {
0648: GeneralRenderer.doSetRect(sData, pw, x0, y0, x0 + 1, y0 + 1);
0649: }
0650:
0651: public void drawScanline(int x0, int x1, int y0) {
0652: GeneralRenderer.doSetRect(sData, pw, x0, y0, x1 + 1, y0 + 1);
0653: }
0654: }
0655:
0656: class SetFillPathANY extends FillPath {
0657: SetFillPathANY() {
0658: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0659: SurfaceType.Any);
0660: }
0661:
0662: public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
0663: int transx, int transy, Path2D.Float p2df) {
0664: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0665: sData);
0666: ProcessPath.fillPath(new PixelWriterDrawHandler(sData, pw, sg2d
0667: .getCompClip(), sg2d.strokeHint), p2df, transx, transy);
0668: }
0669: }
0670:
0671: class SetFillSpansANY extends FillSpans {
0672: SetFillSpansANY() {
0673: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0674: SurfaceType.Any);
0675: }
0676:
0677: public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,
0678: SpanIterator si) {
0679: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0680: sData);
0681:
0682: int span[] = new int[4];
0683: while (si.nextSpan(span)) {
0684: GeneralRenderer.doSetRect(sData, pw, span[0], span[1],
0685: span[2], span[3]);
0686: }
0687: }
0688: }
0689:
0690: class SetDrawLineANY extends DrawLine {
0691: SetDrawLineANY() {
0692: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0693: SurfaceType.Any);
0694: }
0695:
0696: public void DrawLine(SunGraphics2D sg2d, SurfaceData sData, int x1,
0697: int y1, int x2, int y2) {
0698: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0699: sData);
0700:
0701: if (y1 >= y2) {
0702: GeneralRenderer.doDrawLine(sData, pw, null, sg2d
0703: .getCompClip(), x2, y2, x1, y1);
0704: } else {
0705: GeneralRenderer.doDrawLine(sData, pw, null, sg2d
0706: .getCompClip(), x1, y1, x2, y2);
0707: }
0708: }
0709: }
0710:
0711: class SetDrawPolygonsANY extends DrawPolygons {
0712: SetDrawPolygonsANY() {
0713: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0714: SurfaceType.Any);
0715: }
0716:
0717: public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
0718: int xPoints[], int yPoints[], int nPoints[], int numPolys,
0719: int transx, int transy, boolean close) {
0720: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0721: sData);
0722:
0723: int off = 0;
0724: Region clip = sg2d.getCompClip();
0725: for (int i = 0; i < numPolys; i++) {
0726: int numpts = nPoints[i];
0727: GeneralRenderer.doDrawPoly(sData, pw, xPoints, yPoints,
0728: off, numpts, clip, transx, transy, close);
0729: off += numpts;
0730: }
0731: }
0732: }
0733:
0734: class SetDrawPathANY extends DrawPath {
0735: SetDrawPathANY() {
0736: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0737: SurfaceType.Any);
0738: }
0739:
0740: public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
0741: int transx, int transy, Path2D.Float p2df) {
0742: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0743: sData);
0744: ProcessPath.drawPath(new PixelWriterDrawHandler(sData, pw, sg2d
0745: .getCompClip(), sg2d.strokeHint), p2df, transx, transy);
0746: }
0747: }
0748:
0749: class SetDrawRectANY extends DrawRect {
0750: SetDrawRectANY() {
0751: super (SurfaceType.AnyColor, CompositeType.SrcNoEa,
0752: SurfaceType.Any);
0753: }
0754:
0755: public void DrawRect(SunGraphics2D sg2d, SurfaceData sData, int x,
0756: int y, int w, int h) {
0757: PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d,
0758: sData);
0759:
0760: GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);
0761: }
0762: }
0763:
0764: class XorFillRectANY extends FillRect {
0765: XorFillRectANY() {
0766: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0767: }
0768:
0769: public void FillRect(SunGraphics2D sg2d, SurfaceData sData, int x,
0770: int y, int w, int h) {
0771: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0772: sData);
0773:
0774: Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y,
0775: w, h);
0776:
0777: GeneralRenderer.doSetRect(sData, pw, r.getLoX(), r.getLoY(), r
0778: .getHiX(), r.getHiY());
0779: }
0780: }
0781:
0782: class XorFillPathANY extends FillPath {
0783: XorFillPathANY() {
0784: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0785: }
0786:
0787: public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
0788: int transx, int transy, Path2D.Float p2df) {
0789: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0790: sData);
0791: ProcessPath.fillPath(new PixelWriterDrawHandler(sData, pw, sg2d
0792: .getCompClip(), sg2d.strokeHint), p2df, transx, transy);
0793: }
0794: }
0795:
0796: class XorFillSpansANY extends FillSpans {
0797: XorFillSpansANY() {
0798: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0799: }
0800:
0801: public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,
0802: SpanIterator si) {
0803: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0804: sData);
0805:
0806: int span[] = new int[4];
0807: while (si.nextSpan(span)) {
0808: GeneralRenderer.doSetRect(sData, pw, span[0], span[1],
0809: span[2], span[3]);
0810: }
0811: }
0812: }
0813:
0814: class XorDrawLineANY extends DrawLine {
0815: XorDrawLineANY() {
0816: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0817: }
0818:
0819: public void DrawLine(SunGraphics2D sg2d, SurfaceData sData, int x1,
0820: int y1, int x2, int y2) {
0821: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0822: sData);
0823:
0824: if (y1 >= y2) {
0825: GeneralRenderer.doDrawLine(sData, pw, null, sg2d
0826: .getCompClip(), x2, y2, x1, y1);
0827: } else {
0828: GeneralRenderer.doDrawLine(sData, pw, null, sg2d
0829: .getCompClip(), x1, y1, x2, y2);
0830: }
0831: }
0832: }
0833:
0834: class XorDrawPolygonsANY extends DrawPolygons {
0835: XorDrawPolygonsANY() {
0836: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0837: }
0838:
0839: public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
0840: int xPoints[], int yPoints[], int nPoints[], int numPolys,
0841: int transx, int transy, boolean close) {
0842: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0843: sData);
0844:
0845: int off = 0;
0846: Region clip = sg2d.getCompClip();
0847: for (int i = 0; i < numPolys; i++) {
0848: int numpts = nPoints[i];
0849: GeneralRenderer.doDrawPoly(sData, pw, xPoints, yPoints,
0850: off, numpts, clip, transx, transy, close);
0851: off += numpts;
0852: }
0853: }
0854: }
0855:
0856: class XorDrawPathANY extends DrawPath {
0857: XorDrawPathANY() {
0858: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0859: }
0860:
0861: public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
0862: int transx, int transy, Path2D.Float p2df) {
0863: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0864: sData);
0865: ProcessPath.drawPath(new PixelWriterDrawHandler(sData, pw, sg2d
0866: .getCompClip(), sg2d.strokeHint), p2df, transx, transy);
0867: }
0868: }
0869:
0870: class XorDrawRectANY extends DrawRect {
0871: XorDrawRectANY() {
0872: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0873: }
0874:
0875: public void DrawRect(SunGraphics2D sg2d, SurfaceData sData, int x,
0876: int y, int w, int h) {
0877: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0878: sData);
0879:
0880: GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);
0881: }
0882: }
0883:
0884: class XorDrawGlyphListANY extends DrawGlyphList {
0885: XorDrawGlyphListANY() {
0886: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0887: }
0888:
0889: public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData sData,
0890: GlyphList gl) {
0891: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0892: sData);
0893: GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d
0894: .getCompClip());
0895: }
0896: }
0897:
0898: class XorDrawGlyphListAAANY extends DrawGlyphListAA {
0899: XorDrawGlyphListAAANY() {
0900: super (SurfaceType.AnyColor, CompositeType.Xor, SurfaceType.Any);
0901: }
0902:
0903: public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData sData,
0904: GlyphList gl) {
0905: PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d,
0906: sData);
0907: GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d
0908: .getCompClip());
0909: }
0910: }
0911:
0912: abstract class PixelWriter {
0913: protected WritableRaster dstRast;
0914:
0915: public void setRaster(WritableRaster dstRast) {
0916: this .dstRast = dstRast;
0917: }
0918:
0919: public abstract void writePixel(int x, int y);
0920: }
0921:
0922: class SolidPixelWriter extends PixelWriter {
0923: protected Object srcData;
0924:
0925: SolidPixelWriter(Object srcPixel) {
0926: this .srcData = srcPixel;
0927: }
0928:
0929: public void writePixel(int x, int y) {
0930: dstRast.setDataElements(x, y, srcData);
0931: }
0932: }
0933:
0934: abstract class XorPixelWriter extends PixelWriter {
0935: protected ColorModel dstCM;
0936:
0937: public void writePixel(int x, int y) {
0938: Object dstPixel = dstRast.getDataElements(x, y, null);
0939: xorPixel(dstPixel);
0940: dstRast.setDataElements(x, y, dstPixel);
0941: }
0942:
0943: protected abstract void xorPixel(Object pixData);
0944:
0945: public static class ByteData extends XorPixelWriter {
0946: byte[] xorData;
0947:
0948: ByteData(Object srcPixel, Object xorPixel) {
0949: this .xorData = (byte[]) srcPixel;
0950: xorPixel(xorPixel);
0951: this .xorData = (byte[]) xorPixel;
0952: }
0953:
0954: protected void xorPixel(Object pixData) {
0955: byte[] dstData = (byte[]) pixData;
0956: for (int i = 0; i < dstData.length; i++) {
0957: dstData[i] ^= xorData[i];
0958: }
0959: }
0960: }
0961:
0962: public static class ShortData extends XorPixelWriter {
0963: short[] xorData;
0964:
0965: ShortData(Object srcPixel, Object xorPixel) {
0966: this .xorData = (short[]) srcPixel;
0967: xorPixel(xorPixel);
0968: this .xorData = (short[]) xorPixel;
0969: }
0970:
0971: protected void xorPixel(Object pixData) {
0972: short[] dstData = (short[]) pixData;
0973: for (int i = 0; i < dstData.length; i++) {
0974: dstData[i] ^= xorData[i];
0975: }
0976: }
0977: }
0978:
0979: public static class IntData extends XorPixelWriter {
0980: int[] xorData;
0981:
0982: IntData(Object srcPixel, Object xorPixel) {
0983: this .xorData = (int[]) srcPixel;
0984: xorPixel(xorPixel);
0985: this .xorData = (int[]) xorPixel;
0986: }
0987:
0988: protected void xorPixel(Object pixData) {
0989: int[] dstData = (int[]) pixData;
0990: for (int i = 0; i < dstData.length; i++) {
0991: dstData[i] ^= xorData[i];
0992: }
0993: }
0994: }
0995:
0996: public static class FloatData extends XorPixelWriter {
0997: int[] xorData;
0998:
0999: FloatData(Object srcPixel, Object xorPixel) {
1000: float[] srcData = (float[]) srcPixel;
1001: float[] xorData = (float[]) xorPixel;
1002: this .xorData = new int[srcData.length];
1003: for (int i = 0; i < srcData.length; i++) {
1004: this .xorData[i] = (Float.floatToIntBits(srcData[i]) ^ Float
1005: .floatToIntBits(xorData[i]));
1006: }
1007: }
1008:
1009: protected void xorPixel(Object pixData) {
1010: float[] dstData = (float[]) pixData;
1011: for (int i = 0; i < dstData.length; i++) {
1012: int v = Float.floatToIntBits(dstData[i]) ^ xorData[i];
1013: dstData[i] = Float.intBitsToFloat(v);
1014: }
1015: }
1016: }
1017:
1018: public static class DoubleData extends XorPixelWriter {
1019: long[] xorData;
1020:
1021: DoubleData(Object srcPixel, Object xorPixel) {
1022: double[] srcData = (double[]) srcPixel;
1023: double[] xorData = (double[]) xorPixel;
1024: this .xorData = new long[srcData.length];
1025: for (int i = 0; i < srcData.length; i++) {
1026: this .xorData[i] = (Double.doubleToLongBits(srcData[i]) ^ Double
1027: .doubleToLongBits(xorData[i]));
1028: }
1029: }
1030:
1031: protected void xorPixel(Object pixData) {
1032: double[] dstData = (double[]) pixData;
1033: for (int i = 0; i < dstData.length; i++) {
1034: long v = Double.doubleToLongBits(dstData[i])
1035: ^ xorData[i];
1036: dstData[i] = Double.longBitsToDouble(v);
1037: }
1038: }
1039: }
1040: }
|