Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/java2d/loops/GeneralRenderer.java
38918 views
/*1* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* @author Charlton Innovations, Inc.27*/2829package sun.java2d.loops;3031import java.awt.image.WritableRaster;32import java.awt.image.DataBuffer;33import java.awt.image.ColorModel;34import java.awt.geom.Path2D;35import java.awt.geom.PathIterator;36import java.awt.geom.AffineTransform;37import sun.java2d.pipe.Region;38import sun.java2d.pipe.SpanIterator;39import sun.java2d.SunGraphics2D;40import sun.java2d.SurfaceData;41import sun.java2d.loops.ProcessPath;42import sun.font.GlyphList;4344/**45* GeneralRenderer collection46* Basically, a collection of components which permit basic47* rendering to occur on rasters of any format48*/4950public final class GeneralRenderer {51public static void register() {52Class owner = GeneralRenderer.class;53GraphicsPrimitive[] primitives = {54new GraphicsPrimitiveProxy(owner, "SetFillRectANY",55FillRect.methodSignature,56FillRect.primTypeID,57SurfaceType.AnyColor,58CompositeType.SrcNoEa,59SurfaceType.Any),60new GraphicsPrimitiveProxy(owner, "SetFillPathANY",61FillPath.methodSignature,62FillPath.primTypeID,63SurfaceType.AnyColor,64CompositeType.SrcNoEa,65SurfaceType.Any),66new GraphicsPrimitiveProxy(owner, "SetFillSpansANY",67FillSpans.methodSignature,68FillSpans.primTypeID,69SurfaceType.AnyColor,70CompositeType.SrcNoEa,71SurfaceType.Any),72new GraphicsPrimitiveProxy(owner, "SetDrawLineANY",73DrawLine.methodSignature,74DrawLine.primTypeID,75SurfaceType.AnyColor,76CompositeType.SrcNoEa,77SurfaceType.Any),78new GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY",79DrawPolygons.methodSignature,80DrawPolygons.primTypeID,81SurfaceType.AnyColor,82CompositeType.SrcNoEa,83SurfaceType.Any),84new GraphicsPrimitiveProxy(owner, "SetDrawPathANY",85DrawPath.methodSignature,86DrawPath.primTypeID,87SurfaceType.AnyColor,88CompositeType.SrcNoEa,89SurfaceType.Any),90new GraphicsPrimitiveProxy(owner, "SetDrawRectANY",91DrawRect.methodSignature,92DrawRect.primTypeID,93SurfaceType.AnyColor,94CompositeType.SrcNoEa,95SurfaceType.Any),9697new GraphicsPrimitiveProxy(owner, "XorFillRectANY",98FillRect.methodSignature,99FillRect.primTypeID,100SurfaceType.AnyColor,101CompositeType.Xor,102SurfaceType.Any),103new GraphicsPrimitiveProxy(owner, "XorFillPathANY",104FillPath.methodSignature,105FillPath.primTypeID,106SurfaceType.AnyColor,107CompositeType.Xor,108SurfaceType.Any),109new GraphicsPrimitiveProxy(owner, "XorFillSpansANY",110FillSpans.methodSignature,111FillSpans.primTypeID,112SurfaceType.AnyColor,113CompositeType.Xor,114SurfaceType.Any),115new GraphicsPrimitiveProxy(owner, "XorDrawLineANY",116DrawLine.methodSignature,117DrawLine.primTypeID,118SurfaceType.AnyColor,119CompositeType.Xor,120SurfaceType.Any),121new GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY",122DrawPolygons.methodSignature,123DrawPolygons.primTypeID,124SurfaceType.AnyColor,125CompositeType.Xor,126SurfaceType.Any),127new GraphicsPrimitiveProxy(owner, "XorDrawPathANY",128DrawPath.methodSignature,129DrawPath.primTypeID,130SurfaceType.AnyColor,131CompositeType.Xor,132SurfaceType.Any),133new GraphicsPrimitiveProxy(owner, "XorDrawRectANY",134DrawRect.methodSignature,135DrawRect.primTypeID,136SurfaceType.AnyColor,137CompositeType.Xor,138SurfaceType.Any),139new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListANY",140DrawGlyphList.methodSignature,141DrawGlyphList.primTypeID,142SurfaceType.AnyColor,143CompositeType.Xor,144SurfaceType.Any),145new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListAAANY",146DrawGlyphListAA.methodSignature,147DrawGlyphListAA.primTypeID,148SurfaceType.AnyColor,149CompositeType.Xor,150SurfaceType.Any),151};152GraphicsPrimitiveMgr.register(primitives);153}154155static void doDrawPoly(SurfaceData sData, PixelWriter pw,156int xPoints[], int yPoints[], int off, int nPoints,157Region clip, int transx, int transy, boolean close)158{159int mx, my, x1, y1;160int[] tmp = null;161162if (nPoints <= 0) {163return;164}165mx = x1 = xPoints[off] + transx;166my = y1 = yPoints[off] + transy;167while (--nPoints > 0) {168++off;169int x2 = xPoints[off] + transx;170int y2 = yPoints[off] + transy;171tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,172x1, y1, x2, y2);173x1 = x2;174y1 = y2;175}176if (close && (x1 != mx || y1 != my)) {177tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,178x1, y1, mx, my);179}180}181182static void doSetRect(SurfaceData sData, PixelWriter pw,183int x1, int y1, int x2, int y2) {184WritableRaster dstRast =185(WritableRaster) sData.getRaster(x1, y1, x2-x1, y2-y1);186pw.setRaster(dstRast);187188while (y1 < y2) {189for (int x = x1; x < x2; x++) {190pw.writePixel(x, y1);191}192y1++;193}194}195196static int[] doDrawLine(SurfaceData sData, PixelWriter pw, int[] boundPts,197Region clip,198int origx1, int origy1, int origx2, int origy2)199{200if (boundPts == null) {201boundPts = new int[8];202}203boundPts[0] = origx1;204boundPts[1] = origy1;205boundPts[2] = origx2;206boundPts[3] = origy2;207if (!adjustLine(boundPts,208clip.getLoX(), clip.getLoY(),209clip.getHiX(), clip.getHiY()))210{211return boundPts;212}213int x1 = boundPts[0];214int y1 = boundPts[1];215int x2 = boundPts[2];216int y2 = boundPts[3];217218WritableRaster dstRast = (WritableRaster)219sData.getRaster(Math.min(x1, x2), Math.min(y1, y2),220Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1);221pw.setRaster(dstRast);222223/* this could be made smaller, more elegant, more traditional. */224if (x1 == x2) {225if (y1 > y2) {226do {227pw.writePixel(x1, y1);228y1--;229} while (y1 >= y2);230} else {231do {232pw.writePixel(x1, y1);233y1++;234} while (y1 <= y2);235}236} else if (y1 == y2) {237if (x1 > x2) {238do {239pw.writePixel(x1, y1);240x1--;241} while (x1 >= x2);242} else {243do {244pw.writePixel(x1, y1);245x1++;246} while (x1 <= x2);247}248} else {249int dx = boundPts[4];250int dy = boundPts[5];251int ax = boundPts[6];252int ay = boundPts[7];253int steps;254int bumpmajor;255int bumpminor;256int errminor;257int errmajor;258int error;259boolean xmajor;260261if (ax >= ay) {262/* x is dominant */263xmajor = true;264errmajor = ay * 2;265errminor = ax * 2;266bumpmajor = (dx < 0) ? -1 : 1;267bumpminor = (dy < 0) ? -1 : 1;268ax = -ax; /* For clipping adjustment below */269steps = x2 - x1;270} else {271/* y is dominant */272xmajor = false;273errmajor = ax * 2;274errminor = ay * 2;275bumpmajor = (dy < 0) ? -1 : 1;276bumpminor = (dx < 0) ? -1 : 1;277ay = -ay; /* For clipping adjustment below */278steps = y2 - y1;279}280error = - (errminor / 2);281if (y1 != origy1) {282int ysteps = y1 - origy1;283if (ysteps < 0) {284ysteps = -ysteps;285}286error += ysteps * ax * 2;287}288if (x1 != origx1) {289int xsteps = x1 - origx1;290if (xsteps < 0) {291xsteps = -xsteps;292}293error += xsteps * ay * 2;294}295if (steps < 0) {296steps = -steps;297}298if (xmajor) {299do {300pw.writePixel(x1, y1);301x1 += bumpmajor;302error += errmajor;303if (error >= 0) {304y1 += bumpminor;305error -= errminor;306}307} while (--steps >= 0);308} else {309do {310pw.writePixel(x1, y1);311y1 += bumpmajor;312error += errmajor;313if (error >= 0) {314x1 += bumpminor;315error -= errminor;316}317} while (--steps >= 0);318}319}320return boundPts;321}322323public static void doDrawRect(PixelWriter pw,324SunGraphics2D sg2d, SurfaceData sData,325int x, int y, int w, int h)326{327if (w < 0 || h < 0) {328return;329}330int x2 = Region.dimAdd(Region.dimAdd(x, w), 1);331int y2 = Region.dimAdd(Region.dimAdd(y, h), 1);332Region r = sg2d.getCompClip().getBoundsIntersectionXYXY(x, y, x2, y2);333if (r.isEmpty()) {334return;335}336int cx1 = r.getLoX();337int cy1 = r.getLoY();338int cx2 = r.getHiX();339int cy2 = r.getHiY();340341if (w < 2 || h < 2) {342doSetRect(sData, pw, cx1, cy1, cx2, cy2);343return;344}345346347if (cy1 == y) {348doSetRect(sData, pw, cx1, cy1, cx2, cy1+1);349}350if (cx1 == x) {351doSetRect(sData, pw, cx1, cy1+1, cx1+1, cy2-1);352}353if (cx2 == x2) {354doSetRect(sData, pw, cx2-1, cy1+1, cx2, cy2-1);355}356if (cy2 == y2) {357doSetRect(sData, pw, cx1, cy2-1, cx2, cy2);358}359}360361/*362* REMIND: For now this will field both AA and non-AA requests and363* use a simple threshold to choose pixels if the supplied grey364* bits are antialiased. We should really find a way to disable365* AA text at a higher level or to have the GlyphList be able to366* reset the glyphs to non-AA after construction.367*/368static void doDrawGlyphList(SurfaceData sData, PixelWriter pw,369GlyphList gl, Region clip)370{371int[] bounds = gl.getBounds();372clip.clipBoxToBounds(bounds);373int cx1 = bounds[0];374int cy1 = bounds[1];375int cx2 = bounds[2];376int cy2 = bounds[3];377378WritableRaster dstRast =379(WritableRaster) sData.getRaster(cx1, cy1, cx2 - cx1, cy2 - cy1);380pw.setRaster(dstRast);381382int num = gl.getNumGlyphs();383for (int i = 0; i < num; i++) {384gl.setGlyphIndex(i);385int metrics[] = gl.getMetrics();386int gx1 = metrics[0];387int gy1 = metrics[1];388int w = metrics[2];389int gx2 = gx1 + w;390int gy2 = gy1 + metrics[3];391int off = 0;392if (gx1 < cx1) {393off = cx1 - gx1;394gx1 = cx1;395}396if (gy1 < cy1) {397off += (cy1 - gy1) * w;398gy1 = cy1;399}400if (gx2 > cx2) gx2 = cx2;401if (gy2 > cy2) gy2 = cy2;402if (gx2 > gx1 && gy2 > gy1) {403byte alpha[] = gl.getGrayBits();404w -= (gx2 - gx1);405for (int y = gy1; y < gy2; y++) {406for (int x = gx1; x < gx2; x++) {407if (alpha[off++] < 0) {408pw.writePixel(x, y);409}410}411off += w;412}413}414}415}416417static final int OUTCODE_TOP = 1;418static final int OUTCODE_BOTTOM = 2;419static final int OUTCODE_LEFT = 4;420static final int OUTCODE_RIGHT = 8;421422static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) {423int code;424if (y < ymin) {425code = OUTCODE_TOP;426} else if (y > ymax) {427code = OUTCODE_BOTTOM;428} else {429code = 0;430}431if (x < xmin) {432code |= OUTCODE_LEFT;433} else if (x > xmax) {434code |= OUTCODE_RIGHT;435}436return code;437}438439public static boolean adjustLine(int [] boundPts,440int cxmin, int cymin, int cx2, int cy2)441{442int cxmax = cx2 - 1;443int cymax = cy2 - 1;444int x1 = boundPts[0];445int y1 = boundPts[1];446int x2 = boundPts[2];447int y2 = boundPts[3];448449if ((cxmax < cxmin) || (cymax < cymin)) {450return false;451}452453if (x1 == x2) {454if (x1 < cxmin || x1 > cxmax) {455return false;456}457if (y1 > y2) {458int t = y1;459y1 = y2;460y2 = t;461}462if (y1 < cymin) {463y1 = cymin;464}465if (y2 > cymax) {466y2 = cymax;467}468if (y1 > y2) {469return false;470}471boundPts[1] = y1;472boundPts[3] = y2;473} else if (y1 == y2) {474if (y1 < cymin || y1 > cymax) {475return false;476}477if (x1 > x2) {478int t = x1;479x1 = x2;480x2 = t;481}482if (x1 < cxmin) {483x1 = cxmin;484}485if (x2 > cxmax) {486x2 = cxmax;487}488if (x1 > x2) {489return false;490}491boundPts[0] = x1;492boundPts[2] = x2;493} else {494/* REMIND: This could overflow... */495int outcode1, outcode2;496int dx = x2 - x1;497int dy = y2 - y1;498int ax = (dx < 0) ? -dx : dx;499int ay = (dy < 0) ? -dy : dy;500boolean xmajor = (ax >= ay);501502outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);503outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);504while ((outcode1 | outcode2) != 0) {505int xsteps, ysteps;506if ((outcode1 & outcode2) != 0) {507return false;508}509if (outcode1 != 0) {510if (0 != (outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {511if (0 != (outcode1 & OUTCODE_TOP)) {512y1 = cymin;513} else {514y1 = cymax;515}516ysteps = y1 - boundPts[1];517if (ysteps < 0) {518ysteps = -ysteps;519}520xsteps = 2 * ysteps * ax + ay;521if (xmajor) {522xsteps += ay - ax - 1;523}524xsteps = xsteps / (2 * ay);525if (dx < 0) {526xsteps = -xsteps;527}528x1 = boundPts[0] + xsteps;529} else if (0 !=530(outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {531if (0 != (outcode1 & OUTCODE_LEFT)) {532x1 = cxmin;533} else {534x1 = cxmax;535}536xsteps = x1 - boundPts[0];537if (xsteps < 0) {538xsteps = -xsteps;539}540ysteps = 2 * xsteps * ay + ax;541if (!xmajor) {542ysteps += ax - ay - 1;543}544ysteps = ysteps / (2 * ax);545if (dy < 0) {546ysteps = -ysteps;547}548y1 = boundPts[1] + ysteps;549}550outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);551} else {552if (0 != (outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {553if (0 != (outcode2 & OUTCODE_TOP)) {554y2 = cymin;555} else {556y2 = cymax;557}558ysteps = y2 - boundPts[3];559if (ysteps < 0) {560ysteps = -ysteps;561}562xsteps = 2 * ysteps * ax + ay;563if (xmajor) {564xsteps += ay - ax;565} else {566xsteps -= 1;567}568xsteps = xsteps / (2 * ay);569if (dx > 0) {570xsteps = -xsteps;571}572x2 = boundPts[2] + xsteps;573} else if (0 !=574(outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {575if (0 != (outcode2 & OUTCODE_LEFT)) {576x2 = cxmin;577} else {578x2 = cxmax;579}580xsteps = x2 - boundPts[2];581if (xsteps < 0) {582xsteps = -xsteps;583}584ysteps = 2 * xsteps * ay + ax;585if (xmajor) {586ysteps -= 1;587} else {588ysteps += ax - ay;589}590ysteps = ysteps / (2 * ax);591if (dy > 0) {592ysteps = -ysteps;593}594y2 = boundPts[3] + ysteps;595}596outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);597}598}599boundPts[0] = x1;600boundPts[1] = y1;601boundPts[2] = x2;602boundPts[3] = y2;603boundPts[4] = dx;604boundPts[5] = dy;605boundPts[6] = ax;606boundPts[7] = ay;607}608return true;609}610611static PixelWriter createSolidPixelWriter(SunGraphics2D sg2d,612SurfaceData sData)613{614ColorModel dstCM = sData.getColorModel();615Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);616617return new SolidPixelWriter(srcPixel);618}619620static PixelWriter createXorPixelWriter(SunGraphics2D sg2d,621SurfaceData sData)622{623ColorModel dstCM = sData.getColorModel();624625Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);626627XORComposite comp = (XORComposite)sg2d.getComposite();628int xorrgb = comp.getXorColor().getRGB();629Object xorPixel = dstCM.getDataElements(xorrgb, null);630631switch (dstCM.getTransferType()) {632case DataBuffer.TYPE_BYTE:633return new XorPixelWriter.ByteData(srcPixel, xorPixel);634case DataBuffer.TYPE_SHORT:635case DataBuffer.TYPE_USHORT:636return new XorPixelWriter.ShortData(srcPixel, xorPixel);637case DataBuffer.TYPE_INT:638return new XorPixelWriter.IntData(srcPixel, xorPixel);639case DataBuffer.TYPE_FLOAT:640return new XorPixelWriter.FloatData(srcPixel, xorPixel);641case DataBuffer.TYPE_DOUBLE:642return new XorPixelWriter.DoubleData(srcPixel, xorPixel);643default:644throw new InternalError("Unsupported XOR pixel type");645}646}647}648649class SetFillRectANY extends FillRect {650SetFillRectANY() {651super(SurfaceType.AnyColor,652CompositeType.SrcNoEa,653SurfaceType.Any);654}655656public void FillRect(SunGraphics2D sg2d, SurfaceData sData,657int x, int y, int w, int h)658{659PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);660661Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h);662663GeneralRenderer.doSetRect(sData, pw,664r.getLoX(), r.getLoY(),665r.getHiX(), r.getHiY());666}667}668669class PixelWriterDrawHandler extends ProcessPath.DrawHandler {670PixelWriter pw;671SurfaceData sData;672Region clip;673674public PixelWriterDrawHandler(SurfaceData sData, PixelWriter pw,675Region clip, int strokeHint) {676super(clip.getLoX(), clip.getLoY(),677clip.getHiX(), clip.getHiY(),678strokeHint);679this.sData = sData;680this.pw = pw;681this.clip = clip;682}683684public void drawLine(int x0, int y0, int x1, int y1) {685GeneralRenderer.doDrawLine(sData, pw, null, clip,686x0, y0, x1, y1);687}688689public void drawPixel(int x0, int y0) {690GeneralRenderer.doSetRect(sData, pw, x0, y0, x0 + 1, y0 + 1);691}692693public void drawScanline(int x0, int x1, int y0) {694GeneralRenderer.doSetRect(sData, pw, x0, y0, x1 + 1, y0 + 1);695}696}697698class SetFillPathANY extends FillPath {699SetFillPathANY() {700super(SurfaceType.AnyColor, CompositeType.SrcNoEa,701SurfaceType.Any);702}703704public void FillPath(SunGraphics2D sg2d, SurfaceData sData,705int transx, int transy,706Path2D.Float p2df)707{708PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);709ProcessPath.fillPath(710new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),711sg2d.strokeHint),712p2df, transx, transy);713}714}715716class SetFillSpansANY extends FillSpans {717SetFillSpansANY() {718super(SurfaceType.AnyColor,719CompositeType.SrcNoEa,720SurfaceType.Any);721}722723public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,724SpanIterator si)725{726PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);727728int span[] = new int[4];729while (si.nextSpan(span)) {730GeneralRenderer.doSetRect(sData, pw,731span[0], span[1], span[2], span[3]);732}733}734}735736class SetDrawLineANY extends DrawLine {737SetDrawLineANY() {738super(SurfaceType.AnyColor,739CompositeType.SrcNoEa,740SurfaceType.Any);741}742743public void DrawLine(SunGraphics2D sg2d, SurfaceData sData,744int x1, int y1, int x2, int y2)745{746PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);747748if (y1 >= y2) {749GeneralRenderer.doDrawLine(sData, pw, null,750sg2d.getCompClip(),751x2, y2, x1, y1);752} else {753GeneralRenderer.doDrawLine(sData, pw, null,754sg2d.getCompClip(),755x1, y1, x2, y2);756}757}758}759760class SetDrawPolygonsANY extends DrawPolygons {761SetDrawPolygonsANY() {762super(SurfaceType.AnyColor,763CompositeType.SrcNoEa,764SurfaceType.Any);765}766767public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,768int xPoints[], int yPoints[],769int nPoints[], int numPolys,770int transx, int transy,771boolean close)772{773PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);774775int off = 0;776Region clip = sg2d.getCompClip();777for (int i = 0; i < numPolys; i++) {778int numpts = nPoints[i];779GeneralRenderer.doDrawPoly(sData, pw,780xPoints, yPoints, off, numpts,781clip, transx, transy, close);782off += numpts;783}784}785}786787class SetDrawPathANY extends DrawPath {788SetDrawPathANY() {789super(SurfaceType.AnyColor,790CompositeType.SrcNoEa,791SurfaceType.Any);792}793794public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,795int transx, int transy,796Path2D.Float p2df)797{798PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);799ProcessPath.drawPath(800new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),801sg2d.strokeHint),802p2df, transx, transy803);804}805}806807class SetDrawRectANY extends DrawRect {808SetDrawRectANY() {809super(SurfaceType.AnyColor,810CompositeType.SrcNoEa,811SurfaceType.Any);812}813814public void DrawRect(SunGraphics2D sg2d, SurfaceData sData,815int x, int y, int w, int h)816{817PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);818819GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);820}821}822823class XorFillRectANY extends FillRect {824XorFillRectANY() {825super(SurfaceType.AnyColor,826CompositeType.Xor,827SurfaceType.Any);828}829830public void FillRect(SunGraphics2D sg2d, SurfaceData sData,831int x, int y, int w, int h)832{833PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);834835Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h);836837GeneralRenderer.doSetRect(sData, pw,838r.getLoX(), r.getLoY(),839r.getHiX(), r.getHiY());840}841}842843class XorFillPathANY extends FillPath {844XorFillPathANY() {845super(SurfaceType.AnyColor, CompositeType.Xor,846SurfaceType.Any);847}848849public void FillPath(SunGraphics2D sg2d, SurfaceData sData,850int transx, int transy,851Path2D.Float p2df)852{853PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);854ProcessPath.fillPath(855new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),856sg2d.strokeHint),857p2df, transx, transy);858}859}860861class XorFillSpansANY extends FillSpans {862XorFillSpansANY() {863super(SurfaceType.AnyColor,864CompositeType.Xor,865SurfaceType.Any);866}867868public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,869SpanIterator si)870{871PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);872873int span[] = new int[4];874while (si.nextSpan(span)) {875GeneralRenderer.doSetRect(sData, pw,876span[0], span[1], span[2], span[3]);877}878}879}880881class XorDrawLineANY extends DrawLine {882XorDrawLineANY() {883super(SurfaceType.AnyColor,884CompositeType.Xor,885SurfaceType.Any);886}887888public void DrawLine(SunGraphics2D sg2d, SurfaceData sData,889int x1, int y1, int x2, int y2)890{891PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);892893if (y1 >= y2) {894GeneralRenderer.doDrawLine(sData, pw, null,895sg2d.getCompClip(),896x2, y2, x1, y1);897} else {898GeneralRenderer.doDrawLine(sData, pw, null,899sg2d.getCompClip(),900x1, y1, x2, y2);901}902}903}904905class XorDrawPolygonsANY extends DrawPolygons {906XorDrawPolygonsANY() {907super(SurfaceType.AnyColor,908CompositeType.Xor,909SurfaceType.Any);910}911912public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,913int xPoints[], int yPoints[],914int nPoints[], int numPolys,915int transx, int transy,916boolean close)917{918PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);919920int off = 0;921Region clip = sg2d.getCompClip();922for (int i = 0; i < numPolys; i++) {923int numpts = nPoints[i];924GeneralRenderer.doDrawPoly(sData, pw,925xPoints, yPoints, off, numpts,926clip, transx, transy, close);927off += numpts;928}929}930}931932class XorDrawPathANY extends DrawPath {933XorDrawPathANY() {934super(SurfaceType.AnyColor,935CompositeType.Xor,936SurfaceType.Any);937}938939public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,940int transx, int transy, Path2D.Float p2df)941{942PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);943ProcessPath.drawPath(944new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),945sg2d.strokeHint),946p2df, transx, transy947);948}949}950951class XorDrawRectANY extends DrawRect {952XorDrawRectANY() {953super(SurfaceType.AnyColor,954CompositeType.Xor,955SurfaceType.Any);956}957958public void DrawRect(SunGraphics2D sg2d, SurfaceData sData,959int x, int y, int w, int h)960{961PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);962963GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);964}965}966967class XorDrawGlyphListANY extends DrawGlyphList {968XorDrawGlyphListANY() {969super(SurfaceType.AnyColor,970CompositeType.Xor,971SurfaceType.Any);972}973974public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData sData,975GlyphList gl)976{977PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);978GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip());979}980}981982class XorDrawGlyphListAAANY extends DrawGlyphListAA {983XorDrawGlyphListAAANY() {984super(SurfaceType.AnyColor,985CompositeType.Xor,986SurfaceType.Any);987}988989public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData sData,990GlyphList gl)991{992PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);993GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip());994}995}996997abstract class PixelWriter {998protected WritableRaster dstRast;9991000public void setRaster(WritableRaster dstRast) {1001this.dstRast = dstRast;1002}10031004public abstract void writePixel(int x, int y);1005}10061007class SolidPixelWriter extends PixelWriter {1008protected Object srcData;10091010SolidPixelWriter(Object srcPixel) {1011this.srcData = srcPixel;1012}10131014public void writePixel(int x, int y) {1015dstRast.setDataElements(x, y, srcData);1016}1017}10181019abstract class XorPixelWriter extends PixelWriter {1020protected ColorModel dstCM;10211022public void writePixel(int x, int y) {1023Object dstPixel = dstRast.getDataElements(x, y, null);1024xorPixel(dstPixel);1025dstRast.setDataElements(x, y, dstPixel);1026}10271028protected abstract void xorPixel(Object pixData);10291030public static class ByteData extends XorPixelWriter {1031byte[] xorData;10321033ByteData(Object srcPixel, Object xorPixel) {1034this.xorData = (byte[]) srcPixel;1035xorPixel(xorPixel);1036this.xorData = (byte[]) xorPixel;1037}10381039protected void xorPixel(Object pixData) {1040byte[] dstData = (byte[]) pixData;1041for (int i = 0; i < dstData.length; i++) {1042dstData[i] ^= xorData[i];1043}1044}1045}10461047public static class ShortData extends XorPixelWriter {1048short[] xorData;10491050ShortData(Object srcPixel, Object xorPixel) {1051this.xorData = (short[]) srcPixel;1052xorPixel(xorPixel);1053this.xorData = (short[]) xorPixel;1054}10551056protected void xorPixel(Object pixData) {1057short[] dstData = (short[]) pixData;1058for (int i = 0; i < dstData.length; i++) {1059dstData[i] ^= xorData[i];1060}1061}1062}10631064public static class IntData extends XorPixelWriter {1065int[] xorData;10661067IntData(Object srcPixel, Object xorPixel) {1068this.xorData = (int[]) srcPixel;1069xorPixel(xorPixel);1070this.xorData = (int[]) xorPixel;1071}10721073protected void xorPixel(Object pixData) {1074int[] dstData = (int[]) pixData;1075for (int i = 0; i < dstData.length; i++) {1076dstData[i] ^= xorData[i];1077}1078}1079}10801081public static class FloatData extends XorPixelWriter {1082int[] xorData;10831084FloatData(Object srcPixel, Object xorPixel) {1085float[] srcData = (float[]) srcPixel;1086float[] xorData = (float[]) xorPixel;1087this.xorData = new int[srcData.length];1088for (int i = 0; i < srcData.length; i++) {1089this.xorData[i] = (Float.floatToIntBits(srcData[i]) ^1090Float.floatToIntBits(xorData[i]));1091}1092}10931094protected void xorPixel(Object pixData) {1095float[] dstData = (float[]) pixData;1096for (int i = 0; i < dstData.length; i++) {1097int v = Float.floatToIntBits(dstData[i]) ^ xorData[i];1098dstData[i] = Float.intBitsToFloat(v);1099}1100}1101}11021103public static class DoubleData extends XorPixelWriter {1104long[] xorData;11051106DoubleData(Object srcPixel, Object xorPixel) {1107double[] srcData = (double[]) srcPixel;1108double[] xorData = (double[]) xorPixel;1109this.xorData = new long[srcData.length];1110for (int i = 0; i < srcData.length; i++) {1111this.xorData[i] = (Double.doubleToLongBits(srcData[i]) ^1112Double.doubleToLongBits(xorData[i]));1113}1114}11151116protected void xorPixel(Object pixData) {1117double[] dstData = (double[]) pixData;1118for (int i = 0; i < dstData.length; i++) {1119long v = Double.doubleToLongBits(dstData[i]) ^ xorData[i];1120dstData[i] = Double.longBitsToDouble(v);1121}1122}1123}1124}112511261127