001: /*
002: * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * @author Charlton Innovations, Inc.
028: * @author Jim Graham
029: */
030:
031: package sun.java2d.loops;
032:
033: import java.awt.Composite;
034: import java.awt.Rectangle;
035: import java.awt.image.ColorModel;
036: import java.awt.image.DataBuffer;
037: import java.awt.image.Raster;
038: import java.awt.image.WritableRaster;
039: import sun.awt.image.IntegerComponentRaster;
040: import sun.java2d.SurfaceData;
041: import sun.java2d.pipe.Region;
042: import sun.java2d.pipe.SpanIterator;
043:
044: /**
045: * CustomComponent, collection of GraphicsPrimitive
046: * Basically, this collection of components performs conversion from
047: * ANY to ANY via opaque copy
048: */
049: public final class CustomComponent {
050: public static void register() {
051: // REMIND: This does not work for all destinations yet since
052: // the screen SurfaceData objects do not implement getRaster
053: Class owner = CustomComponent.class;
054: GraphicsPrimitive[] primitives = {
055: new GraphicsPrimitiveProxy(owner,
056: "OpaqueCopyAnyToArgb", Blit.methodSignature,
057: Blit.primTypeID, SurfaceType.Any,
058: CompositeType.SrcNoEa, SurfaceType.IntArgb),
059: new GraphicsPrimitiveProxy(owner,
060: "OpaqueCopyArgbToAny", Blit.methodSignature,
061: Blit.primTypeID, SurfaceType.IntArgb,
062: CompositeType.SrcNoEa, SurfaceType.Any),
063: new GraphicsPrimitiveProxy(owner, "XorCopyArgbToAny",
064: Blit.methodSignature, Blit.primTypeID,
065: SurfaceType.IntArgb, CompositeType.Xor,
066: SurfaceType.Any), };
067: GraphicsPrimitiveMgr.register(primitives);
068: }
069:
070: public static Region getRegionOfInterest(SurfaceData src,
071: SurfaceData dst, Region clip, int srcx, int srcy, int dstx,
072: int dsty, int w, int h) {
073: /*
074: * Intersect all of:
075: * - operation area (dstx, dsty, w, h)
076: * - destination bounds
077: * - (translated) src bounds
078: * - supplied clip (may be non-rectangular)
079: * Intersect the rectangular regions first since those are
080: * simpler operations.
081: */
082: Region ret = Region.getInstanceXYWH(dstx, dsty, w, h);
083: ret = ret.getIntersection(dst.getBounds());
084: Rectangle r = src.getBounds();
085: // srcxy in src space maps to dstxy in dst space
086: r.translate(dstx - srcx, dsty - srcy);
087: ret = ret.getIntersection(r);
088: if (clip != null) {
089: // Intersect with clip last since it may be non-rectangular
090: ret = ret.getIntersection(clip);
091: }
092: return ret;
093: }
094: }
095:
096: /**
097: * ANY format to ARGB format Blit
098: */
099: class OpaqueCopyAnyToArgb extends Blit {
100: OpaqueCopyAnyToArgb() {
101: super (SurfaceType.Any, CompositeType.SrcNoEa,
102: SurfaceType.IntArgb);
103: }
104:
105: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
106: Region clip, int srcx, int srcy, int dstx, int dsty, int w,
107: int h) {
108: Raster srcRast = src.getRaster(srcx, srcy, w, h);
109: ColorModel srcCM = src.getColorModel();
110:
111: Raster dstRast = dst.getRaster(dstx, dsty, w, h);
112: IntegerComponentRaster icr = (IntegerComponentRaster) dstRast;
113: int[] dstPix = icr.getDataStorage();
114:
115: Region roi = CustomComponent.getRegionOfInterest(src, dst,
116: clip, srcx, srcy, dstx, dsty, w, h);
117: SpanIterator si = roi.getSpanIterator();
118:
119: Object srcPix = null;
120:
121: int dstScan = icr.getScanlineStride();
122: // assert(icr.getPixelStride() == 1);
123: srcx -= dstx;
124: srcy -= dsty;
125: int span[] = new int[4];
126: while (si.nextSpan(span)) {
127: int rowoff = icr.getDataOffset(0) + span[1] * dstScan
128: + span[0];
129: for (int y = span[1]; y < span[3]; y++) {
130: int off = rowoff;
131: for (int x = span[0]; x < span[2]; x++) {
132: srcPix = srcRast.getDataElements(x + srcx,
133: y + srcy, srcPix);
134: dstPix[off++] = srcCM.getRGB(srcPix);
135: }
136: rowoff += dstScan;
137: }
138: }
139: // Pixels in the dest were modified directly, we must
140: // manually notify the raster that it was modified
141: icr.markDirty();
142: // REMIND: We need to do something to make sure that dstRast
143: // is put back to the destination (as in the native Release
144: // function)
145: // src.releaseRaster(srcRast); // NOP?
146: // dst.releaseRaster(dstRast);
147: }
148: }
149:
150: /**
151: * ARGB format to ANY format Blit
152: */
153: class OpaqueCopyArgbToAny extends Blit {
154: OpaqueCopyArgbToAny() {
155: super (SurfaceType.IntArgb, CompositeType.SrcNoEa,
156: SurfaceType.Any);
157: }
158:
159: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
160: Region clip, int srcx, int srcy, int dstx, int dsty, int w,
161: int h) {
162: Raster srcRast = src.getRaster(srcx, srcy, w, h);
163: IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;
164: int[] srcPix = icr.getDataStorage();
165:
166: WritableRaster dstRast = (WritableRaster) dst.getRaster(dstx,
167: dsty, w, h);
168: ColorModel dstCM = dst.getColorModel();
169:
170: Region roi = CustomComponent.getRegionOfInterest(src, dst,
171: clip, srcx, srcy, dstx, dsty, w, h);
172: SpanIterator si = roi.getSpanIterator();
173:
174: Object dstPix = null;
175:
176: int srcScan = icr.getScanlineStride();
177: // assert(icr.getPixelStride() == 1);
178: srcx -= dstx;
179: srcy -= dsty;
180: int span[] = new int[4];
181: while (si.nextSpan(span)) {
182: int rowoff = (icr.getDataOffset(0) + (srcy + span[1])
183: * srcScan + (srcx + span[0]));
184: for (int y = span[1]; y < span[3]; y++) {
185: int off = rowoff;
186: for (int x = span[0]; x < span[2]; x++) {
187: dstPix = dstCM.getDataElements(srcPix[off++],
188: dstPix);
189: dstRast.setDataElements(x, y, dstPix);
190: }
191: rowoff += srcScan;
192: }
193: }
194: // REMIND: We need to do something to make sure that dstRast
195: // is put back to the destination (as in the native Release
196: // function)
197: // src.releaseRaster(srcRast); // NOP?
198: // dst.releaseRaster(dstRast);
199: }
200: }
201:
202: /**
203: * ARGB format to ANY format Blit (pixels are XORed together with XOR pixel)
204: */
205: class XorCopyArgbToAny extends Blit {
206: XorCopyArgbToAny() {
207: super (SurfaceType.IntArgb, CompositeType.Xor, SurfaceType.Any);
208: }
209:
210: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
211: Region clip, int srcx, int srcy, int dstx, int dsty, int w,
212: int h) {
213: Raster srcRast = src.getRaster(srcx, srcy, w, h);
214: IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;
215: int[] srcPix = icr.getDataStorage();
216:
217: WritableRaster dstRast = (WritableRaster) dst.getRaster(dstx,
218: dsty, w, h);
219: ColorModel dstCM = dst.getColorModel();
220:
221: Region roi = CustomComponent.getRegionOfInterest(src, dst,
222: clip, srcx, srcy, dstx, dsty, w, h);
223: SpanIterator si = roi.getSpanIterator();
224:
225: int xorrgb = ((XORComposite) comp).getXorColor().getRGB();
226: Object xorPixel = dstCM.getDataElements(xorrgb, null);
227:
228: Object srcPixel = null;
229: Object dstPixel = null;
230:
231: int srcScan = icr.getScanlineStride();
232: // assert(icr.getPixelStride() == 1);
233: srcx -= dstx;
234: srcy -= dsty;
235: int span[] = new int[4];
236: while (si.nextSpan(span)) {
237: int rowoff = (icr.getDataOffset(0) + (srcy + span[1])
238: * srcScan + (srcx + span[0]));
239: for (int y = span[1]; y < span[3]; y++) {
240: int off = rowoff;
241: for (int x = span[0]; x < span[2]; x++) {
242: // REMIND: alpha bits of the destination pixel are
243: // currently altered by the XOR operation, but
244: // should be left untouched
245: srcPixel = dstCM.getDataElements(srcPix[off++],
246: srcPixel);
247: dstPixel = dstRast.getDataElements(x, y, dstPixel);
248:
249: switch (dstCM.getTransferType()) {
250: case DataBuffer.TYPE_BYTE:
251: byte[] bytesrcarr = (byte[]) srcPixel;
252: byte[] bytedstarr = (byte[]) dstPixel;
253: byte[] bytexorarr = (byte[]) xorPixel;
254: for (int i = 0; i < bytedstarr.length; i++) {
255: bytedstarr[i] ^= bytesrcarr[i]
256: ^ bytexorarr[i];
257: }
258: break;
259: case DataBuffer.TYPE_SHORT:
260: case DataBuffer.TYPE_USHORT:
261: short[] shortsrcarr = (short[]) srcPixel;
262: short[] shortdstarr = (short[]) dstPixel;
263: short[] shortxorarr = (short[]) xorPixel;
264: for (int i = 0; i < shortdstarr.length; i++) {
265: shortdstarr[i] ^= shortsrcarr[i]
266: ^ shortxorarr[i];
267: }
268: break;
269: case DataBuffer.TYPE_INT:
270: int[] intsrcarr = (int[]) srcPixel;
271: int[] intdstarr = (int[]) dstPixel;
272: int[] intxorarr = (int[]) xorPixel;
273: for (int i = 0; i < intdstarr.length; i++) {
274: intdstarr[i] ^= intsrcarr[i] ^ intxorarr[i];
275: }
276: break;
277: case DataBuffer.TYPE_FLOAT:
278: float[] floatsrcarr = (float[]) srcPixel;
279: float[] floatdstarr = (float[]) dstPixel;
280: float[] floatxorarr = (float[]) xorPixel;
281: for (int i = 0; i < floatdstarr.length; i++) {
282: int v = (Float
283: .floatToIntBits(floatdstarr[i])
284: ^ Float
285: .floatToIntBits(floatsrcarr[i]) ^ Float
286: .floatToIntBits(floatxorarr[i]));
287: floatdstarr[i] = Float.intBitsToFloat(v);
288: }
289: break;
290: case DataBuffer.TYPE_DOUBLE:
291: double[] doublesrcarr = (double[]) srcPixel;
292: double[] doubledstarr = (double[]) dstPixel;
293: double[] doublexorarr = (double[]) xorPixel;
294: for (int i = 0; i < doubledstarr.length; i++) {
295: long v = (Double
296: .doubleToLongBits(doubledstarr[i])
297: ^ Double
298: .doubleToLongBits(doublesrcarr[i]) ^ Double
299: .doubleToLongBits(doublexorarr[i]));
300: doubledstarr[i] = Double
301: .longBitsToDouble(v);
302: }
303: break;
304: default:
305: throw new InternalError(
306: "Unsupported XOR pixel type");
307: }
308: dstRast.setDataElements(x, y, dstPixel);
309: }
310: rowoff += srcScan;
311: }
312: }
313: // REMIND: We need to do something to make sure that dstRast
314: // is put back to the destination (as in the native Release
315: // function)
316: // src.releaseRaster(srcRast); // NOP?
317: // dst.releaseRaster(dstRast);
318: }
319: }
|