blob: d25324fc921a65170245c9e99df10d5df07c0347 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2004 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
26package sun.java2d.loops;
27
28import java.awt.Composite;
29import java.lang.ref.WeakReference;
30import sun.java2d.loops.GraphicsPrimitive;
31import sun.java2d.SurfaceData;
32import sun.java2d.pipe.Region;
33
34/**
35 * MaskBlit
36 * 1) copies rectangle of pixels from one surface to another
37 * 2) performs compositing of colors based upon a Composite
38 * parameter
39 * 3) blends result of composite with destination using an
40 * alpha coverage mask
41 * 4) the mask may be null in which case it should be treated
42 * as if it were an array of all opaque values (0xff)
43 *
44 * precise behavior is undefined if the source surface
45 * and the destination surface are the same surface
46 * with overlapping regions of pixels
47 */
48
49public class MaskBlit extends GraphicsPrimitive
50{
51 public static final String methodSignature = "MaskBlit(...)".toString();
52
53 public static final int primTypeID = makePrimTypeID();
54
55 private static RenderCache blitcache = new RenderCache(20);
56
57 public static MaskBlit locate(SurfaceType srctype,
58 CompositeType comptype,
59 SurfaceType dsttype)
60 {
61 return (MaskBlit)
62 GraphicsPrimitiveMgr.locate(primTypeID,
63 srctype, comptype, dsttype);
64 }
65
66 public static MaskBlit getFromCache(SurfaceType src,
67 CompositeType comp,
68 SurfaceType dst)
69 {
70 Object o = blitcache.get(src, comp, dst);
71 if (o != null) {
72 return (MaskBlit) o;
73 }
74 MaskBlit blit = locate(src, comp, dst);
75 if (blit == null) {
76 System.out.println("mask blit loop not found for:");
77 System.out.println("src: "+src);
78 System.out.println("comp: "+comp);
79 System.out.println("dst: "+dst);
80 } else {
81 blitcache.put(src, comp, dst, blit);
82 }
83 return blit;
84 }
85
86 protected MaskBlit(SurfaceType srctype,
87 CompositeType comptype,
88 SurfaceType dsttype)
89 {
90 super(methodSignature, primTypeID, srctype, comptype, dsttype);
91 }
92
93 public MaskBlit(long pNativePrim,
94 SurfaceType srctype,
95 CompositeType comptype,
96 SurfaceType dsttype)
97 {
98 super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
99 }
100
101 /**
102 * All MaskBlit implementors must have this invoker method
103 */
104 public native void MaskBlit(SurfaceData src, SurfaceData dst,
105 Composite comp, Region clip,
106 int srcx, int srcy,
107 int dstx, int dsty,
108 int width, int height,
109 byte[] mask, int maskoff, int maskscan);
110
111 static {
112 GraphicsPrimitiveMgr.registerGeneral(new MaskBlit(null, null, null));
113 }
114
115 public GraphicsPrimitive makePrimitive(SurfaceType srctype,
116 CompositeType comptype,
117 SurfaceType dsttype)
118 {
119 /*
120 new Throwable().printStackTrace();
121 System.out.println("Constructing general maskblit for:");
122 System.out.println("src: "+srctype);
123 System.out.println("comp: "+comptype);
124 System.out.println("dst: "+dsttype);
125 */
126
127 if (CompositeType.Xor.equals(comptype)) {
128 throw new InternalError("Cannot construct MaskBlit for " +
129 "XOR mode");
130 }
131
132 General ob = new General(srctype, comptype, dsttype);
133 setupGeneralBinaryOp(ob);
134 return ob;
135 }
136
137 private static class General
138 extends MaskBlit
139 implements GeneralBinaryOp
140 {
141 Blit convertsrc;
142 Blit convertdst;
143 MaskBlit performop;
144 Blit convertresult;
145
146 WeakReference srcTmp;
147 WeakReference dstTmp;
148
149 public General(SurfaceType srctype,
150 CompositeType comptype,
151 SurfaceType dsttype)
152 {
153 super(srctype, comptype, dsttype);
154 }
155
156 public void setPrimitives(Blit srcconverter,
157 Blit dstconverter,
158 GraphicsPrimitive genericop,
159 Blit resconverter)
160 {
161 this.convertsrc = srcconverter;
162 this.convertdst = dstconverter;
163 this.performop = (MaskBlit) genericop;
164 this.convertresult = resconverter;
165 }
166
167 public synchronized void MaskBlit(SurfaceData srcData,
168 SurfaceData dstData,
169 Composite comp,
170 Region clip,
171 int srcx, int srcy,
172 int dstx, int dsty,
173 int width, int height,
174 byte mask[], int offset, int scan)
175 {
176 SurfaceData src, dst;
177 Region opclip;
178 int sx, sy, dx, dy;
179
180 if (convertsrc == null) {
181 src = srcData;
182 sx = srcx;
183 sy = srcy;
184 } else {
185 SurfaceData cachedSrc = null;
186 if (srcTmp != null) {
187 cachedSrc = (SurfaceData) srcTmp.get();
188 }
189 src = convertFrom(convertsrc, srcData, srcx, srcy,
190 width, height, cachedSrc);
191 sx = 0;
192 sy = 0;
193 if (src != cachedSrc) {
194 srcTmp = new WeakReference(src);
195 }
196 }
197
198 if (convertdst == null) {
199 dst = dstData;
200 dx = dstx;
201 dy = dsty;
202 opclip = clip;
203 } else {
204 // assert: convertresult != null
205 SurfaceData cachedDst = null;
206 if (dstTmp != null) {
207 cachedDst = (SurfaceData) dstTmp.get();
208 }
209 dst = convertFrom(convertdst, dstData, dstx, dsty,
210 width, height, cachedDst);
211 dx = 0;
212 dy = 0;
213 opclip = null;
214 if (dst != cachedDst) {
215 dstTmp = new WeakReference(dst);
216 }
217 }
218
219 performop.MaskBlit(src, dst, comp, opclip,
220 sx, sy, dx, dy, width, height,
221 mask, offset, scan);
222
223 if (convertresult != null) {
224 // assert: convertdst != null
225 convertTo(convertresult, dst, dstData, clip,
226 dstx, dsty, width, height);
227 }
228 }
229 }
230
231 public GraphicsPrimitive traceWrap() {
232 return new TraceMaskBlit(this);
233 }
234
235 private static class TraceMaskBlit extends MaskBlit {
236 MaskBlit target;
237
238 public TraceMaskBlit(MaskBlit target) {
239 // We need to have the same NativePrim as our
240 // target in case we are used with a TransformHelper
241 super(target.getNativePrim(),
242 target.getSourceType(),
243 target.getCompositeType(),
244 target.getDestType());
245 this.target = target;
246 }
247
248 public GraphicsPrimitive traceWrap() {
249 return this;
250 }
251
252 public void MaskBlit(SurfaceData src, SurfaceData dst,
253 Composite comp, Region clip,
254 int srcx, int srcy, int dstx, int dsty,
255 int width, int height,
256 byte[] mask, int maskoff, int maskscan)
257 {
258 tracePrimitive(target);
259 target.MaskBlit(src, dst, comp, clip,
260 srcx, srcy, dstx, dsty, width, height,
261 mask, maskoff, maskscan);
262 }
263 }
264}