Path: blob/master/src/java.desktop/share/classes/sun/java2d/loops/CustomComponent.java
41159 views
/*1* Copyright (c) 1997, 2018, 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* @author Jim Graham28*/2930package sun.java2d.loops;3132import java.awt.Composite;33import java.awt.Rectangle;34import java.awt.image.ColorModel;35import java.awt.image.DataBuffer;36import java.awt.image.Raster;37import java.awt.image.WritableRaster;38import sun.awt.image.IntegerComponentRaster;39import sun.java2d.SurfaceData;40import sun.java2d.pipe.Region;41import sun.java2d.pipe.SpanIterator;4243/**44* CustomComponent, collection of GraphicsPrimitive45* Basically, this collection of components performs conversion from46* ANY to ANY via opaque copy47*/48public final class CustomComponent {49public static void register() {50// REMIND: This does not work for all destinations yet since51// the screen SurfaceData objects do not implement getRaster52Class<?> owner = CustomComponent.class;53GraphicsPrimitive[] primitives = {54new GraphicsPrimitiveProxy(owner, "OpaqueCopyAnyToArgb",55Blit.methodSignature,56Blit.primTypeID,57SurfaceType.Any,58CompositeType.SrcNoEa,59SurfaceType.IntArgb),60new GraphicsPrimitiveProxy(owner, "OpaqueCopyArgbToAny",61Blit.methodSignature,62Blit.primTypeID,63SurfaceType.IntArgb,64CompositeType.SrcNoEa,65SurfaceType.Any),66new GraphicsPrimitiveProxy(owner, "XorCopyArgbToAny",67Blit.methodSignature,68Blit.primTypeID,69SurfaceType.IntArgb,70CompositeType.Xor,71SurfaceType.Any),72};73GraphicsPrimitiveMgr.register(primitives);74}7576public static Region getRegionOfInterest(SurfaceData src, SurfaceData dst,77Region clip,78int srcx, int srcy,79int dstx, int dsty,80int w, int h)81{82/*83* Intersect all of:84* - operation area (dstx, dsty, w, h)85* - destination bounds86* - (translated) src bounds87* - supplied clip (may be non-rectangular)88* Intersect the rectangular regions first since those are89* simpler operations.90*/91Region ret = Region.getInstanceXYWH(dstx, dsty, w, h);92ret = ret.getIntersection(dst.getBounds());93Rectangle r = src.getBounds();94// srcxy in src space maps to dstxy in dst space95r.translate(dstx - srcx, dsty - srcy);96ret = ret.getIntersection(r);97if (clip != null) {98// Intersect with clip last since it may be non-rectangular99ret = ret.getIntersection(clip);100}101return ret;102}103}104105/**106* ANY format to ARGB format Blit107*/108class OpaqueCopyAnyToArgb extends Blit {109OpaqueCopyAnyToArgb() {110super(SurfaceType.Any,111CompositeType.SrcNoEa,112SurfaceType.IntArgb);113}114115public void Blit(SurfaceData src, SurfaceData dst,116Composite comp, Region clip,117int srcx, int srcy, int dstx, int dsty, int w, int h)118{119Raster srcRast = src.getRaster(srcx, srcy, w, h);120ColorModel srcCM = src.getColorModel();121122Raster dstRast = dst.getRaster(dstx, dsty, w, h);123IntegerComponentRaster icr = (IntegerComponentRaster) dstRast;124int[] dstPix = icr.getDataStorage();125126Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,127srcx, srcy,128dstx, dsty, w, h);129SpanIterator si = roi.getSpanIterator();130131Object srcPix = null;132133int dstScan = icr.getScanlineStride();134// assert(icr.getPixelStride() == 1);135srcx -= dstx;136srcy -= dsty;137int[] span = new int[4];138while (si.nextSpan(span)) {139int rowoff = icr.getDataOffset(0) + span[1] * dstScan + span[0];140for (int y = span[1]; y < span[3]; y++) {141int off = rowoff;142for (int x = span[0]; x < span[2]; x++) {143srcPix = srcRast.getDataElements(x+srcx, y+srcy, srcPix);144dstPix[off++] = srcCM.getRGB(srcPix);145}146rowoff += dstScan;147}148}149// Pixels in the dest were modified directly, we must150// manually notify the raster that it was modified151icr.markDirty();152// REMIND: We need to do something to make sure that dstRast153// is put back to the destination (as in the native Release154// function)155// src.releaseRaster(srcRast); // NOP?156// dst.releaseRaster(dstRast);157}158}159160/**161* ARGB format to ANY format Blit162*/163class OpaqueCopyArgbToAny extends Blit {164OpaqueCopyArgbToAny() {165super(SurfaceType.IntArgb,166CompositeType.SrcNoEa,167SurfaceType.Any);168}169170public void Blit(SurfaceData src, SurfaceData dst,171Composite comp, Region clip,172int srcx, int srcy, int dstx, int dsty, int w, int h)173{174Raster srcRast = src.getRaster(srcx, srcy, w, h);175IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;176int[] srcPix = icr.getDataStorage();177178WritableRaster dstRast =179(WritableRaster) dst.getRaster(dstx, dsty, w, h);180ColorModel dstCM = dst.getColorModel();181182Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,183srcx, srcy,184dstx, dsty, w, h);185SpanIterator si = roi.getSpanIterator();186187Object dstPix = null;188189int srcScan = icr.getScanlineStride();190// assert(icr.getPixelStride() == 1);191srcx -= dstx;192srcy -= dsty;193int[] span = new int[4];194while (si.nextSpan(span)) {195int rowoff = (icr.getDataOffset(0) +196(srcy + span[1]) * srcScan +197(srcx + span[0]));198for (int y = span[1]; y < span[3]; y++) {199int off = rowoff;200for (int x = span[0]; x < span[2]; x++) {201dstPix = dstCM.getDataElements(srcPix[off++], dstPix);202dstRast.setDataElements(x, y, dstPix);203}204rowoff += srcScan;205}206}207// REMIND: We need to do something to make sure that dstRast208// is put back to the destination (as in the native Release209// function)210// src.releaseRaster(srcRast); // NOP?211// dst.releaseRaster(dstRast);212}213}214215/**216* ARGB format to ANY format Blit (pixels are XORed together with XOR pixel)217*/218class XorCopyArgbToAny extends Blit {219XorCopyArgbToAny() {220super(SurfaceType.IntArgb,221CompositeType.Xor,222SurfaceType.Any);223}224225public void Blit(SurfaceData src, SurfaceData dst,226Composite comp, Region clip,227int srcx, int srcy, int dstx, int dsty, int w, int h)228{229Raster srcRast = src.getRaster(srcx, srcy, w, h);230IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;231int[] srcPix = icr.getDataStorage();232233WritableRaster dstRast =234(WritableRaster) dst.getRaster(dstx, dsty, w, h);235ColorModel dstCM = dst.getColorModel();236237Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,238srcx, srcy,239dstx, dsty, w, h);240SpanIterator si = roi.getSpanIterator();241242int xorrgb = ((XORComposite)comp).getXorColor().getRGB();243Object xorPixel = dstCM.getDataElements(xorrgb, null);244245Object srcPixel = null;246Object dstPixel = null;247248int srcScan = icr.getScanlineStride();249// assert(icr.getPixelStride() == 1);250srcx -= dstx;251srcy -= dsty;252int[] span = new int[4];253while (si.nextSpan(span)) {254int rowoff = (icr.getDataOffset(0) +255(srcy + span[1]) * srcScan +256(srcx + span[0]));257for (int y = span[1]; y < span[3]; y++) {258int off = rowoff;259for (int x = span[0]; x < span[2]; x++) {260// REMIND: alpha bits of the destination pixel are261// currently altered by the XOR operation, but262// should be left untouched263srcPixel = dstCM.getDataElements(srcPix[off++], srcPixel);264dstPixel = dstRast.getDataElements(x, y, dstPixel);265266switch (dstCM.getTransferType()) {267case DataBuffer.TYPE_BYTE:268byte[] bytesrcarr = (byte[]) srcPixel;269byte[] bytedstarr = (byte[]) dstPixel;270byte[] bytexorarr = (byte[]) xorPixel;271for (int i = 0; i < bytedstarr.length; i++) {272bytedstarr[i] ^= bytesrcarr[i] ^ bytexorarr[i];273}274break;275case DataBuffer.TYPE_SHORT:276case DataBuffer.TYPE_USHORT:277short[] shortsrcarr = (short[]) srcPixel;278short[] shortdstarr = (short[]) dstPixel;279short[] shortxorarr = (short[]) xorPixel;280for (int i = 0; i < shortdstarr.length; i++) {281shortdstarr[i] ^= shortsrcarr[i] ^ shortxorarr[i];282}283break;284case DataBuffer.TYPE_INT:285int[] intsrcarr = (int[]) srcPixel;286int[] intdstarr = (int[]) dstPixel;287int[] intxorarr = (int[]) xorPixel;288for (int i = 0; i < intdstarr.length; i++) {289intdstarr[i] ^= intsrcarr[i] ^ intxorarr[i];290}291break;292case DataBuffer.TYPE_FLOAT:293float[] floatsrcarr = (float[]) srcPixel;294float[] floatdstarr = (float[]) dstPixel;295float[] floatxorarr = (float[]) xorPixel;296for (int i = 0; i < floatdstarr.length; i++) {297int v = (Float.floatToIntBits(floatdstarr[i]) ^298Float.floatToIntBits(floatsrcarr[i]) ^299Float.floatToIntBits(floatxorarr[i]));300floatdstarr[i] = Float.intBitsToFloat(v);301}302break;303case DataBuffer.TYPE_DOUBLE:304double[] doublesrcarr = (double[]) srcPixel;305double[] doubledstarr = (double[]) dstPixel;306double[] doublexorarr = (double[]) xorPixel;307for (int i = 0; i < doubledstarr.length; i++) {308long v = (Double.doubleToLongBits(doubledstarr[i]) ^309Double.doubleToLongBits(doublesrcarr[i]) ^310Double.doubleToLongBits(doublexorarr[i]));311doubledstarr[i] = Double.longBitsToDouble(v);312}313break;314default:315throw new InternalError("Unsupported XOR pixel type");316}317dstRast.setDataElements(x, y, dstPixel);318}319rowoff += srcScan;320}321}322// REMIND: We need to do something to make sure that dstRast323// is put back to the destination (as in the native Release324// function)325// src.releaseRaster(srcRast); // NOP?326// dst.releaseRaster(dstRast);327}328}329330331