1 /* 2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @author Charlton Innovations, Inc. 28 * @author Jim Graham 29 */ 30 31 package sun.java2d.loops; 32 33 import java.awt.Composite; 34 import java.awt.Rectangle; 35 import java.awt.image.ColorModel; 36 import java.awt.image.DataBuffer; 37 import java.awt.image.Raster; 38 import java.awt.image.WritableRaster; 39 import sun.awt.image.IntegerComponentRaster; 40 import sun.java2d.SurfaceData; 41 import sun.java2d.pipe.Region; 42 import 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 */ 49 public 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 */ 109 class 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 */ 164 class 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 */ 219 class 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 }