001: /*
002: * Copyright 1999-2004 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: package sun.java2d.loops;
027:
028: import java.awt.Composite;
029: import java.lang.ref.WeakReference;
030: import sun.java2d.loops.GraphicsPrimitive;
031: import sun.java2d.SurfaceData;
032: import sun.java2d.pipe.Region;
033:
034: /**
035: * MaskBlit
036: * 1) copies rectangle of pixels from one surface to another
037: * 2) performs compositing of colors based upon a Composite
038: * parameter
039: * 3) blends result of composite with destination using an
040: * alpha coverage mask
041: * 4) the mask may be null in which case it should be treated
042: * as if it were an array of all opaque values (0xff)
043: *
044: * precise behavior is undefined if the source surface
045: * and the destination surface are the same surface
046: * with overlapping regions of pixels
047: */
048:
049: public class MaskBlit extends GraphicsPrimitive {
050: public static final String methodSignature = "MaskBlit(...)"
051: .toString();
052:
053: public static final int primTypeID = makePrimTypeID();
054:
055: private static RenderCache blitcache = new RenderCache(20);
056:
057: public static MaskBlit locate(SurfaceType srctype,
058: CompositeType comptype, SurfaceType dsttype) {
059: return (MaskBlit) GraphicsPrimitiveMgr.locate(primTypeID,
060: srctype, comptype, dsttype);
061: }
062:
063: public static MaskBlit getFromCache(SurfaceType src,
064: CompositeType comp, SurfaceType dst) {
065: Object o = blitcache.get(src, comp, dst);
066: if (o != null) {
067: return (MaskBlit) o;
068: }
069: MaskBlit blit = locate(src, comp, dst);
070: if (blit == null) {
071: System.out.println("mask blit loop not found for:");
072: System.out.println("src: " + src);
073: System.out.println("comp: " + comp);
074: System.out.println("dst: " + dst);
075: } else {
076: blitcache.put(src, comp, dst, blit);
077: }
078: return blit;
079: }
080:
081: protected MaskBlit(SurfaceType srctype, CompositeType comptype,
082: SurfaceType dsttype) {
083: super (methodSignature, primTypeID, srctype, comptype, dsttype);
084: }
085:
086: public MaskBlit(long pNativePrim, SurfaceType srctype,
087: CompositeType comptype, SurfaceType dsttype) {
088: super (pNativePrim, methodSignature, primTypeID, srctype,
089: comptype, dsttype);
090: }
091:
092: /**
093: * All MaskBlit implementors must have this invoker method
094: */
095: public native void MaskBlit(SurfaceData src, SurfaceData dst,
096: Composite comp, Region clip, int srcx, int srcy, int dstx,
097: int dsty, int width, int height, byte[] mask, int maskoff,
098: int maskscan);
099:
100: static {
101: GraphicsPrimitiveMgr.registerGeneral(new MaskBlit(null, null,
102: null));
103: }
104:
105: public GraphicsPrimitive makePrimitive(SurfaceType srctype,
106: CompositeType comptype, SurfaceType dsttype) {
107: /*
108: new Throwable().printStackTrace();
109: System.out.println("Constructing general maskblit for:");
110: System.out.println("src: "+srctype);
111: System.out.println("comp: "+comptype);
112: System.out.println("dst: "+dsttype);
113: */
114:
115: if (CompositeType.Xor.equals(comptype)) {
116: throw new InternalError("Cannot construct MaskBlit for "
117: + "XOR mode");
118: }
119:
120: General ob = new General(srctype, comptype, dsttype);
121: setupGeneralBinaryOp(ob);
122: return ob;
123: }
124:
125: private static class General extends MaskBlit implements
126: GeneralBinaryOp {
127: Blit convertsrc;
128: Blit convertdst;
129: MaskBlit performop;
130: Blit convertresult;
131:
132: WeakReference srcTmp;
133: WeakReference dstTmp;
134:
135: public General(SurfaceType srctype, CompositeType comptype,
136: SurfaceType dsttype) {
137: super (srctype, comptype, dsttype);
138: }
139:
140: public void setPrimitives(Blit srcconverter, Blit dstconverter,
141: GraphicsPrimitive genericop, Blit resconverter) {
142: this .convertsrc = srcconverter;
143: this .convertdst = dstconverter;
144: this .performop = (MaskBlit) genericop;
145: this .convertresult = resconverter;
146: }
147:
148: public synchronized void MaskBlit(SurfaceData srcData,
149: SurfaceData dstData, Composite comp, Region clip,
150: int srcx, int srcy, int dstx, int dsty, int width,
151: int height, byte mask[], int offset, int scan) {
152: SurfaceData src, dst;
153: Region opclip;
154: int sx, sy, dx, dy;
155:
156: if (convertsrc == null) {
157: src = srcData;
158: sx = srcx;
159: sy = srcy;
160: } else {
161: SurfaceData cachedSrc = null;
162: if (srcTmp != null) {
163: cachedSrc = (SurfaceData) srcTmp.get();
164: }
165: src = convertFrom(convertsrc, srcData, srcx, srcy,
166: width, height, cachedSrc);
167: sx = 0;
168: sy = 0;
169: if (src != cachedSrc) {
170: srcTmp = new WeakReference(src);
171: }
172: }
173:
174: if (convertdst == null) {
175: dst = dstData;
176: dx = dstx;
177: dy = dsty;
178: opclip = clip;
179: } else {
180: // assert: convertresult != null
181: SurfaceData cachedDst = null;
182: if (dstTmp != null) {
183: cachedDst = (SurfaceData) dstTmp.get();
184: }
185: dst = convertFrom(convertdst, dstData, dstx, dsty,
186: width, height, cachedDst);
187: dx = 0;
188: dy = 0;
189: opclip = null;
190: if (dst != cachedDst) {
191: dstTmp = new WeakReference(dst);
192: }
193: }
194:
195: performop.MaskBlit(src, dst, comp, opclip, sx, sy, dx, dy,
196: width, height, mask, offset, scan);
197:
198: if (convertresult != null) {
199: // assert: convertdst != null
200: convertTo(convertresult, dst, dstData, clip, dstx,
201: dsty, width, height);
202: }
203: }
204: }
205:
206: public GraphicsPrimitive traceWrap() {
207: return new TraceMaskBlit(this );
208: }
209:
210: private static class TraceMaskBlit extends MaskBlit {
211: MaskBlit target;
212:
213: public TraceMaskBlit(MaskBlit target) {
214: // We need to have the same NativePrim as our
215: // target in case we are used with a TransformHelper
216: super (target.getNativePrim(), target.getSourceType(),
217: target.getCompositeType(), target.getDestType());
218: this .target = target;
219: }
220:
221: public GraphicsPrimitive traceWrap() {
222: return this ;
223: }
224:
225: public void MaskBlit(SurfaceData src, SurfaceData dst,
226: Composite comp, Region clip, int srcx, int srcy,
227: int dstx, int dsty, int width, int height, byte[] mask,
228: int maskoff, int maskscan) {
229: tracePrimitive(target);
230: target.MaskBlit(src, dst, comp, clip, srcx, srcy, dstx,
231: dsty, width, height, mask, maskoff, maskscan);
232: }
233: }
234: }
|