1N/A/*
1N/A * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
1N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1N/A *
1N/A * This code is free software; you can redistribute it and/or modify it
1N/A * under the terms of the GNU General Public License version 2 only, as
1N/A * published by the Free Software Foundation. Oracle designates this
1N/A * particular file as subject to the "Classpath" exception as provided
1N/A * by Oracle in the LICENSE file that accompanied this code.
1N/A *
1N/A * This code is distributed in the hope that it will be useful, but WITHOUT
1N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1N/A * version 2 for more details (a copy is included in the LICENSE file that
1N/A * accompanied this code).
1N/A *
1N/A * You should have received a copy of the GNU General Public License version
1N/A * 2 along with this work; if not, write to the Free Software Foundation,
1N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1N/A *
1N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1N/A * or visit www.oracle.com if you need additional information or have any
1N/A * questions.
1N/A */
1N/A
1N/A/*
1N/A * @author Charlton Innovations, Inc.
1N/A */
1N/A
1N/Apackage sun.java2d.loops;
1N/A
1N/Aimport java.awt.image.WritableRaster;
1N/Aimport java.awt.image.DataBuffer;
1N/Aimport java.awt.image.ColorModel;
1N/Aimport java.awt.geom.Path2D;
1N/Aimport java.awt.geom.PathIterator;
1N/Aimport java.awt.geom.AffineTransform;
1N/Aimport sun.java2d.pipe.Region;
1N/Aimport sun.java2d.pipe.SpanIterator;
1N/Aimport sun.java2d.SunGraphics2D;
1N/Aimport sun.java2d.SurfaceData;
1N/Aimport sun.java2d.loops.ProcessPath;
1N/Aimport sun.font.GlyphList;
1N/A
1N/A/**
1N/A * GeneralRenderer collection
1N/A * Basically, a collection of components which permit basic
1N/A * rendering to occur on rasters of any format
1N/A */
1N/A
1N/Apublic final class GeneralRenderer {
1N/A public static void register() {
1N/A Class owner = GeneralRenderer.class;
1N/A GraphicsPrimitive[] primitives = {
1N/A new GraphicsPrimitiveProxy(owner, "SetFillRectANY",
1N/A FillRect.methodSignature,
1N/A FillRect.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "SetFillPathANY",
1N/A FillPath.methodSignature,
1N/A FillPath.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "SetFillSpansANY",
1N/A FillSpans.methodSignature,
1N/A FillSpans.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "SetDrawLineANY",
1N/A DrawLine.methodSignature,
1N/A DrawLine.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY",
1N/A DrawPolygons.methodSignature,
1N/A DrawPolygons.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "SetDrawPathANY",
1N/A DrawPath.methodSignature,
1N/A DrawPath.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "SetDrawRectANY",
1N/A DrawRect.methodSignature,
1N/A DrawRect.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.SrcNoEa,
1N/A SurfaceType.Any),
1N/A
1N/A new GraphicsPrimitiveProxy(owner, "XorFillRectANY",
1N/A FillRect.methodSignature,
1N/A FillRect.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorFillPathANY",
1N/A FillPath.methodSignature,
1N/A FillPath.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorFillSpansANY",
1N/A FillSpans.methodSignature,
1N/A FillSpans.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorDrawLineANY",
1N/A DrawLine.methodSignature,
1N/A DrawLine.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY",
1N/A DrawPolygons.methodSignature,
1N/A DrawPolygons.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorDrawPathANY",
1N/A DrawPath.methodSignature,
1N/A DrawPath.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorDrawRectANY",
1N/A DrawRect.methodSignature,
1N/A DrawRect.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListANY",
1N/A DrawGlyphList.methodSignature,
1N/A DrawGlyphList.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListAAANY",
1N/A DrawGlyphListAA.methodSignature,
1N/A DrawGlyphListAA.primTypeID,
1N/A SurfaceType.AnyColor,
1N/A CompositeType.Xor,
1N/A SurfaceType.Any),
1N/A };
1N/A GraphicsPrimitiveMgr.register(primitives);
1N/A }
1N/A
1N/A static void doDrawPoly(SurfaceData sData, PixelWriter pw,
1N/A int xPoints[], int yPoints[], int off, int nPoints,
1N/A Region clip, int transx, int transy, boolean close)
1N/A {
1N/A int mx, my, x1, y1;
1N/A int[] tmp = null;
1N/A
1N/A if (nPoints <= 0) {
1N/A return;
1N/A }
1N/A mx = x1 = xPoints[off] + transx;
1N/A my = y1 = yPoints[off] + transy;
1N/A while (--nPoints > 0) {
1N/A ++off;
1N/A int x2 = xPoints[off] + transx;
1N/A int y2 = yPoints[off] + transy;
1N/A tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,
1N/A x1, y1, x2, y2);
1N/A x1 = x2;
1N/A y1 = y2;
1N/A }
1N/A if (close && (x1 != mx || y1 != my)) {
1N/A tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,
1N/A x1, y1, mx, my);
1N/A }
1N/A }
1N/A
1N/A static void doSetRect(SurfaceData sData, PixelWriter pw,
1N/A int x1, int y1, int x2, int y2) {
1N/A WritableRaster dstRast =
1N/A (WritableRaster) sData.getRaster(x1, y1, x2-x1, y2-y1);
1N/A pw.setRaster(dstRast);
1N/A
1N/A while (y1 < y2) {
1N/A for (int x = x1; x < x2; x++) {
1N/A pw.writePixel(x, y1);
1N/A }
1N/A y1++;
1N/A }
1N/A }
1N/A
1N/A static int[] doDrawLine(SurfaceData sData, PixelWriter pw, int[] boundPts,
1N/A Region clip,
1N/A int origx1, int origy1, int origx2, int origy2)
1N/A {
1N/A if (boundPts == null) {
1N/A boundPts = new int[8];
1N/A }
1N/A boundPts[0] = origx1;
1N/A boundPts[1] = origy1;
1N/A boundPts[2] = origx2;
1N/A boundPts[3] = origy2;
1N/A if (!adjustLine(boundPts,
1N/A clip.getLoX(), clip.getLoY(),
1N/A clip.getHiX(), clip.getHiY()))
1N/A {
1N/A return boundPts;
1N/A }
1N/A int x1 = boundPts[0];
1N/A int y1 = boundPts[1];
1N/A int x2 = boundPts[2];
1N/A int y2 = boundPts[3];
1N/A
1N/A WritableRaster dstRast = (WritableRaster)
1N/A sData.getRaster(Math.min(x1, x2), Math.min(y1, y2),
1N/A Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1);
1N/A pw.setRaster(dstRast);
1N/A
1N/A /* this could be made smaller, more elegant, more traditional. */
1N/A if (x1 == x2) {
1N/A if (y1 > y2) {
1N/A do {
1N/A pw.writePixel(x1, y1);
1N/A y1--;
1N/A } while (y1 >= y2);
1N/A } else {
1N/A do {
1N/A pw.writePixel(x1, y1);
1N/A y1++;
1N/A } while (y1 <= y2);
1N/A }
1N/A } else if (y1 == y2) {
1N/A if (x1 > x2) {
1N/A do {
1N/A pw.writePixel(x1, y1);
1N/A x1--;
1N/A } while (x1 >= x2);
1N/A } else {
1N/A do {
1N/A pw.writePixel(x1, y1);
1N/A x1++;
1N/A } while (x1 <= x2);
1N/A }
1N/A } else {
1N/A int dx = boundPts[4];
1N/A int dy = boundPts[5];
1N/A int ax = boundPts[6];
1N/A int ay = boundPts[7];
1N/A int steps;
1N/A int bumpmajor;
1N/A int bumpminor;
1N/A int errminor;
1N/A int errmajor;
1N/A int error;
1N/A boolean xmajor;
1N/A
1N/A if (ax >= ay) {
1N/A /* x is dominant */
1N/A xmajor = true;
1N/A errmajor = ay * 2;
1N/A errminor = ax * 2;
1N/A bumpmajor = (dx < 0) ? -1 : 1;
1N/A bumpminor = (dy < 0) ? -1 : 1;
1N/A ax = -ax; /* For clipping adjustment below */
1N/A steps = x2 - x1;
1N/A } else {
1N/A /* y is dominant */
1N/A xmajor = false;
1N/A errmajor = ax * 2;
1N/A errminor = ay * 2;
1N/A bumpmajor = (dy < 0) ? -1 : 1;
1N/A bumpminor = (dx < 0) ? -1 : 1;
1N/A ay = -ay; /* For clipping adjustment below */
1N/A 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);
}
}
}
}