blob: dec47c782702802ee17cc5ddd426199e62f84e94 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2002 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.pipe;
27
28import java.lang.ref.WeakReference;
29import java.awt.Rectangle;
30import java.awt.Shape;
31import java.awt.PaintContext;
32import java.awt.Transparency;
33import java.awt.image.ColorModel;
34import java.awt.image.Raster;
35import java.awt.image.WritableRaster;
36import java.awt.image.BufferedImage;
37import sun.awt.image.BufImgSurfaceData;
38import sun.java2d.SunGraphics2D;
39import sun.java2d.SurfaceData;
40import sun.java2d.loops.Blit;
41import sun.java2d.loops.MaskBlit;
42import sun.java2d.loops.CompositeType;
43import sun.java2d.loops.GraphicsPrimitiveMgr;
44
45/**
46 * This class implements a CompositePipe that renders path alpha tiles
47 * into a destination according to the Composite attribute of a
48 * SunGraphics2D.
49 */
50public class AlphaPaintPipe implements CompositePipe {
51 static WeakReference cachedLastRaster;
52 static WeakReference cachedLastColorModel;
53 static WeakReference cachedLastData;
54
55 static class TileContext {
56 SunGraphics2D sunG2D;
57 PaintContext paintCtxt;
58 ColorModel paintModel;
59 WeakReference lastRaster;
60 WeakReference lastData;
61 MaskBlit lastMask;
62 Blit lastBlit;
63 SurfaceData dstData;
64
65 public TileContext(SunGraphics2D sg, PaintContext pc) {
66 sunG2D = sg;
67 paintCtxt = pc;
68 paintModel = pc.getColorModel();
69 dstData = sg.getSurfaceData();
70 synchronized (AlphaPaintPipe.class) {
71 if (cachedLastColorModel != null &&
72 cachedLastColorModel.get() == paintModel)
73 {
74 this.lastRaster = cachedLastRaster;
75 this.lastData = cachedLastData;
76 }
77 }
78 }
79 }
80
81 public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
82 int[] abox) {
83 PaintContext paintContext =
84 sg.paint.createContext(sg.getDeviceColorModel(),
85 devR,
86 s.getBounds2D(),
87 sg.cloneTransform(),
88 sg.getRenderingHints());
89 return new TileContext(sg, paintContext);
90 }
91
92 public boolean needTile(Object context, int x, int y, int w, int h) {
93 return true;
94 }
95
96 private static final int TILE_SIZE = 32;
97
98 public void renderPathTile(Object ctx,
99 byte[] atile, int offset, int tilesize,
100 int x, int y, int w, int h) {
101 TileContext context = (TileContext) ctx;
102 PaintContext paintCtxt = context.paintCtxt;
103 SunGraphics2D sg = context.sunG2D;
104 SurfaceData dstData = context.dstData;
105 SurfaceData srcData = null;
106 Raster lastRas = null;
107 if (context.lastData != null && context.lastRaster != null) {
108 srcData = (SurfaceData) context.lastData.get();
109 lastRas = (Raster) context.lastRaster.get();
110 if (srcData == null || lastRas == null) {
111 srcData = null;
112 lastRas = null;
113 }
114 }
115 ColorModel paintModel = context.paintModel;
116
117 for (int rely = 0; rely < h; rely += TILE_SIZE) {
118 int ty = y + rely;
119 int th = Math.min(h-rely, TILE_SIZE);
120 for (int relx = 0; relx < w; relx += TILE_SIZE) {
121 int tx = x + relx;
122 int tw = Math.min(w-relx, TILE_SIZE);
123
124 Raster srcRaster = paintCtxt.getRaster(tx, ty, tw, th);
125 if ((srcRaster.getMinX() != 0) || (srcRaster.getMinY() != 0)) {
126 srcRaster = srcRaster.createTranslatedChild(0, 0);
127 }
128 if (lastRas != srcRaster) {
129 lastRas = srcRaster;
130 context.lastRaster = new WeakReference(lastRas);
131 // REMIND: This will fail for a non-Writable raster!
132 BufferedImage bImg =
133 new BufferedImage(paintModel,
134 (WritableRaster) srcRaster,
135 paintModel.isAlphaPremultiplied(),
136 null);
137 srcData = BufImgSurfaceData.createData(bImg);
138 context.lastData = new WeakReference(srcData);
139 context.lastMask = null;
140 context.lastBlit = null;
141 }
142
143 if (atile == null) {
144 if (context.lastBlit == null) {
145 CompositeType comptype = sg.imageComp;
146 if (CompositeType.SrcOverNoEa.equals(comptype) &&
147 paintModel.getTransparency() == Transparency.OPAQUE)
148 {
149 comptype = CompositeType.SrcNoEa;
150 }
151 context.lastBlit =
152 Blit.getFromCache(srcData.getSurfaceType(),
153 comptype,
154 dstData.getSurfaceType());
155 }
156 context.lastBlit.Blit(srcData, dstData,
157 sg.composite, null,
158 0, 0, tx, ty, tw, th);
159 } else {
160 if (context.lastMask == null) {
161 CompositeType comptype = sg.imageComp;
162 if (CompositeType.SrcOverNoEa.equals(comptype) &&
163 paintModel.getTransparency() == Transparency.OPAQUE)
164 {
165 comptype = CompositeType.SrcNoEa;
166 }
167 context.lastMask =
168 MaskBlit.getFromCache(srcData.getSurfaceType(),
169 comptype,
170 dstData.getSurfaceType());
171 }
172
173 int toff = offset + rely * tilesize + relx;
174 context.lastMask.MaskBlit(srcData, dstData,
175 sg.composite, null,
176 0, 0, tx, ty, tw, th,
177 atile, toff, tilesize);
178 }
179 }
180 }
181 }
182
183 public void skipTile(Object context, int x, int y) {
184 return;
185 }
186
187 public void endSequence(Object ctx) {
188 TileContext context = (TileContext) ctx;
189 if (context.paintCtxt != null) {
190 context.paintCtxt.dispose();
191 }
192 synchronized (AlphaPaintPipe.class) {
193 if (context.lastData != null) {
194 cachedLastRaster = context.lastRaster;
195 if (cachedLastColorModel == null ||
196 cachedLastColorModel.get() != context.paintModel)
197 {
198 // Avoid creating new WeakReference if possible
199 cachedLastColorModel =
200 new WeakReference(context.paintModel);
201 }
202 cachedLastData = context.lastData;
203 }
204 }
205 }
206}