blob: 9b208f255dd72dc692ea47daae2a2ea5e76c8a6c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26/*
27 * @author Charlton Innovations, Inc.
28 * @author Jim Graham
29 */
30
31package sun.java2d.loops;
32
33import java.awt.Composite;
34import java.awt.Rectangle;
35import java.awt.image.ColorModel;
36import java.awt.image.DataBuffer;
37import java.awt.image.Raster;
38import java.awt.image.WritableRaster;
39import sun.awt.image.IntegerComponentRaster;
40import sun.java2d.SurfaceData;
41import sun.java2d.pipe.Region;
42import sun.java2d.pipe.SpanIterator;
43
44/**
45 * CustomComponent, collection of GraphicsPrimitive
46 * Basically, this collection of components performs conversion from
47 * ANY to ANY via opaque copy
48 */
49public final class CustomComponent {
50 public static void register() {
51 // REMIND: This does not work for all destinations yet since
52 // the screen SurfaceData objects do not implement getRaster
53 Class owner = CustomComponent.class;
54 GraphicsPrimitive[] primitives = {
55 new GraphicsPrimitiveProxy(owner, "OpaqueCopyAnyToArgb",
56 Blit.methodSignature,
57 Blit.primTypeID,
58 SurfaceType.Any,
59 CompositeType.SrcNoEa,
60 SurfaceType.IntArgb),
61 new GraphicsPrimitiveProxy(owner, "OpaqueCopyArgbToAny",
62 Blit.methodSignature,
63 Blit.primTypeID,
64 SurfaceType.IntArgb,
65 CompositeType.SrcNoEa,
66 SurfaceType.Any),
67 new GraphicsPrimitiveProxy(owner, "XorCopyArgbToAny",
68 Blit.methodSignature,
69 Blit.primTypeID,
70 SurfaceType.IntArgb,
71 CompositeType.Xor,
72 SurfaceType.Any),
73 };
74 GraphicsPrimitiveMgr.register(primitives);
75 }
76
77 public static Region getRegionOfInterest(SurfaceData src, SurfaceData dst,
78 Region clip,
79 int srcx, int srcy,
80 int dstx, int dsty,
81 int w, int h)
82 {
83 /*
84 * Intersect all of:
85 * - operation area (dstx, dsty, w, h)
86 * - destination bounds
87 * - (translated) src bounds
88 * - supplied clip (may be non-rectangular)
89 * Intersect the rectangular regions first since those are
90 * simpler operations.
91 */
92 Region ret = Region.getInstanceXYWH(dstx, dsty, w, h);
93 ret = ret.getIntersection(dst.getBounds());
94 Rectangle r = src.getBounds();
95 // srcxy in src space maps to dstxy in dst space
96 r.translate(dstx - srcx, dsty - srcy);
97 ret = ret.getIntersection(r);
98 if (clip != null) {
99 // Intersect with clip last since it may be non-rectangular
100 ret = ret.getIntersection(clip);
101 }
102 return ret;
103 }
104}
105
106/**
107 * ANY format to ARGB format Blit
108 */
109class OpaqueCopyAnyToArgb extends Blit {
110 OpaqueCopyAnyToArgb() {
111 super(SurfaceType.Any,
112 CompositeType.SrcNoEa,
113 SurfaceType.IntArgb);
114 }
115
116 public void Blit(SurfaceData src, SurfaceData dst,
117 Composite comp, Region clip,
118 int srcx, int srcy, int dstx, int dsty, int w, int h)
119 {
120 Raster srcRast = src.getRaster(srcx, srcy, w, h);
121 ColorModel srcCM = src.getColorModel();
122
123 Raster dstRast = dst.getRaster(dstx, dsty, w, h);
124 IntegerComponentRaster icr = (IntegerComponentRaster) dstRast;
125 int[] dstPix = icr.getDataStorage();
126
127 Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,
128 srcx, srcy,
129 dstx, dsty, w, h);
130 SpanIterator si = roi.getSpanIterator();
131
132 Object srcPix = null;
133
134 int dstScan = icr.getScanlineStride();
135 // assert(icr.getPixelStride() == 1);
136 srcx -= dstx;
137 srcy -= dsty;
138 int span[] = new int[4];
139 while (si.nextSpan(span)) {
140 int rowoff = icr.getDataOffset(0) + span[1] * dstScan + span[0];
141 for (int y = span[1]; y < span[3]; y++) {
142 int off = rowoff;
143 for (int x = span[0]; x < span[2]; x++) {
144 srcPix = srcRast.getDataElements(x+srcx, y+srcy, srcPix);
145 dstPix[off++] = srcCM.getRGB(srcPix);
146 }
147 rowoff += dstScan;
148 }
149 }
150 // Pixels in the dest were modified directly, we must
151 // manually notify the raster that it was modified
152 icr.markDirty();
153 // REMIND: We need to do something to make sure that dstRast
154 // is put back to the destination (as in the native Release
155 // function)
156 // src.releaseRaster(srcRast); // NOP?
157 // dst.releaseRaster(dstRast);
158 }
159}
160
161/**
162 * ARGB format to ANY format Blit
163 */
164class OpaqueCopyArgbToAny extends Blit {
165 OpaqueCopyArgbToAny() {
166 super(SurfaceType.IntArgb,
167 CompositeType.SrcNoEa,
168 SurfaceType.Any);
169 }
170
171 public void Blit(SurfaceData src, SurfaceData dst,
172 Composite comp, Region clip,
173 int srcx, int srcy, int dstx, int dsty, int w, int h)
174 {
175 Raster srcRast = src.getRaster(srcx, srcy, w, h);
176 IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;
177 int[] srcPix = icr.getDataStorage();
178
179 WritableRaster dstRast =
180 (WritableRaster) dst.getRaster(dstx, dsty, w, h);
181 ColorModel dstCM = dst.getColorModel();
182
183 Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,
184 srcx, srcy,
185 dstx, dsty, w, h);
186 SpanIterator si = roi.getSpanIterator();
187
188 Object dstPix = null;
189
190 int srcScan = icr.getScanlineStride();
191 // assert(icr.getPixelStride() == 1);
192 srcx -= dstx;
193 srcy -= dsty;
194 int span[] = new int[4];
195 while (si.nextSpan(span)) {
196 int rowoff = (icr.getDataOffset(0) +
197 (srcy + span[1]) * srcScan +
198 (srcx + span[0]));
199 for (int y = span[1]; y < span[3]; y++) {
200 int off = rowoff;
201 for (int x = span[0]; x < span[2]; x++) {
202 dstPix = dstCM.getDataElements(srcPix[off++], dstPix);
203 dstRast.setDataElements(x, y, dstPix);
204 }
205 rowoff += srcScan;
206 }
207 }
208 // REMIND: We need to do something to make sure that dstRast
209 // is put back to the destination (as in the native Release
210 // function)
211 // src.releaseRaster(srcRast); // NOP?
212 // dst.releaseRaster(dstRast);
213 }
214}
215
216/**
217 * ARGB format to ANY format Blit (pixels are XORed together with XOR pixel)
218 */
219class XorCopyArgbToAny extends Blit {
220 XorCopyArgbToAny() {
221 super(SurfaceType.IntArgb,
222 CompositeType.Xor,
223 SurfaceType.Any);
224 }
225
226 public void Blit(SurfaceData src, SurfaceData dst,
227 Composite comp, Region clip,
228 int srcx, int srcy, int dstx, int dsty, int w, int h)
229 {
230 Raster srcRast = src.getRaster(srcx, srcy, w, h);
231 IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;
232 int[] srcPix = icr.getDataStorage();
233
234 WritableRaster dstRast =
235 (WritableRaster) dst.getRaster(dstx, dsty, w, h);
236 ColorModel dstCM = dst.getColorModel();
237
238 Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,
239 srcx, srcy,
240 dstx, dsty, w, h);
241 SpanIterator si = roi.getSpanIterator();
242
243 int xorrgb = ((XORComposite)comp).getXorColor().getRGB();
244 Object xorPixel = dstCM.getDataElements(xorrgb, null);
245
246 Object srcPixel = null;
247 Object dstPixel = null;
248
249 int srcScan = icr.getScanlineStride();
250 // assert(icr.getPixelStride() == 1);
251 srcx -= dstx;
252 srcy -= dsty;
253 int span[] = new int[4];
254 while (si.nextSpan(span)) {
255 int rowoff = (icr.getDataOffset(0) +
256 (srcy + span[1]) * srcScan +
257 (srcx + span[0]));
258 for (int y = span[1]; y < span[3]; y++) {
259 int off = rowoff;
260 for (int x = span[0]; x < span[2]; x++) {
261 // REMIND: alpha bits of the destination pixel are
262 // currently altered by the XOR operation, but
263 // should be left untouched
264 srcPixel = dstCM.getDataElements(srcPix[off++], srcPixel);
265 dstPixel = dstRast.getDataElements(x, y, dstPixel);
266
267 switch (dstCM.getTransferType()) {
268 case DataBuffer.TYPE_BYTE:
269 byte[] bytesrcarr = (byte[]) srcPixel;
270 byte[] bytedstarr = (byte[]) dstPixel;
271 byte[] bytexorarr = (byte[]) xorPixel;
272 for (int i = 0; i < bytedstarr.length; i++) {
273 bytedstarr[i] ^= bytesrcarr[i] ^ bytexorarr[i];
274 }
275 break;
276 case DataBuffer.TYPE_SHORT:
277 case DataBuffer.TYPE_USHORT:
278 short[] shortsrcarr = (short[]) srcPixel;
279 short[] shortdstarr = (short[]) dstPixel;
280 short[] shortxorarr = (short[]) xorPixel;
281 for (int i = 0; i < shortdstarr.length; i++) {
282 shortdstarr[i] ^= shortsrcarr[i] ^ shortxorarr[i];
283 }
284 break;
285 case DataBuffer.TYPE_INT:
286 int[] intsrcarr = (int[]) srcPixel;
287 int[] intdstarr = (int[]) dstPixel;
288 int[] intxorarr = (int[]) xorPixel;
289 for (int i = 0; i < intdstarr.length; i++) {
290 intdstarr[i] ^= intsrcarr[i] ^ intxorarr[i];
291 }
292 break;
293 case DataBuffer.TYPE_FLOAT:
294 float[] floatsrcarr = (float[]) srcPixel;
295 float[] floatdstarr = (float[]) dstPixel;
296 float[] floatxorarr = (float[]) xorPixel;
297 for (int i = 0; i < floatdstarr.length; i++) {
298 int v = (Float.floatToIntBits(floatdstarr[i]) ^
299 Float.floatToIntBits(floatsrcarr[i]) ^
300 Float.floatToIntBits(floatxorarr[i]));
301 floatdstarr[i] = Float.intBitsToFloat(v);
302 }
303 break;
304 case DataBuffer.TYPE_DOUBLE:
305 double[] doublesrcarr = (double[]) srcPixel;
306 double[] doubledstarr = (double[]) dstPixel;
307 double[] doublexorarr = (double[]) xorPixel;
308 for (int i = 0; i < doubledstarr.length; i++) {
309 long v = (Double.doubleToLongBits(doubledstarr[i]) ^
310 Double.doubleToLongBits(doublesrcarr[i]) ^
311 Double.doubleToLongBits(doublexorarr[i]));
312 doubledstarr[i] = Double.longBitsToDouble(v);
313 }
314 break;
315 default:
316 throw new InternalError("Unsupported XOR pixel type");
317 }
318 dstRast.setDataElements(x, y, dstPixel);
319 }
320 rowoff += srcScan;
321 }
322 }
323 // REMIND: We need to do something to make sure that dstRast
324 // is put back to the destination (as in the native Release
325 // function)
326 // src.releaseRaster(srcRast); // NOP?
327 // dst.releaseRaster(dstRast);
328 }
329}