1 /* 2 * Copyright (c) 1999, 2010, 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 package sun.java2d.loops; 27 28 import java.awt.Paint; 29 import java.awt.PaintContext; 30 import java.awt.Composite; 31 import java.awt.Rectangle; 32 import java.awt.image.ColorModel; 33 import java.awt.image.BufferedImage; 34 import java.awt.image.WritableRaster; 35 import sun.awt.image.BufImgSurfaceData; 36 import sun.java2d.loops.GraphicsPrimitive; 37 import sun.java2d.SunGraphics2D; 38 import sun.java2d.SurfaceData; 39 import sun.java2d.pipe.Region; 40 41 /** 42 * MaskFill 43 * 1) fills rectangles of pixels on a surface 44 * 2) performs compositing of colors based upon a Composite 45 * parameter 46 * 3) blends result of composite with destination using an 47 * alpha coverage mask 48 * 4) the mask may be null in which case it should be treated 49 * as if it were an array of all opaque values (0xff) 50 */ 51 public class MaskFill extends GraphicsPrimitive 52 { 53 public static final String methodSignature = "MaskFill(...)".toString(); 54 public static final String fillPgramSignature = 55 "FillAAPgram(...)".toString(); 56 public static final String drawPgramSignature = 57 "DrawAAPgram(...)".toString(); 58 59 public static final int primTypeID = makePrimTypeID(); 60 61 private static RenderCache fillcache = new RenderCache(10); 62 63 public static MaskFill locate(SurfaceType srctype, 64 CompositeType comptype, 65 SurfaceType dsttype) 66 { 67 return (MaskFill) 68 GraphicsPrimitiveMgr.locate(primTypeID, 69 srctype, comptype, dsttype); 70 } 71 72 public static MaskFill locatePrim(SurfaceType srctype, 73 CompositeType comptype, 74 SurfaceType dsttype) 75 { 76 return (MaskFill) 77 GraphicsPrimitiveMgr.locatePrim(primTypeID, 78 srctype, comptype, dsttype); 79 } 80 81 /* 82 * Note that this uses locatePrim, not locate, so it can return 83 * null if there is no specific loop to handle this op... 84 */ 85 public static MaskFill getFromCache(SurfaceType src, 86 CompositeType comp, 87 SurfaceType dst) 88 { 89 Object o = fillcache.get(src, comp, dst); 90 if (o != null) { 91 return (MaskFill) o; 92 } 93 MaskFill fill = locatePrim(src, comp, dst); 94 if (fill != null) { 95 fillcache.put(src, comp, dst, fill); 96 } 97 return fill; 98 } 99 100 protected MaskFill(String alternateSignature, 101 SurfaceType srctype, 102 CompositeType comptype, 103 SurfaceType dsttype) 104 { 105 super(alternateSignature, primTypeID, srctype, comptype, dsttype); 106 } 107 108 protected MaskFill(SurfaceType srctype, 109 CompositeType comptype, 110 SurfaceType dsttype) 111 { 112 super(methodSignature, primTypeID, srctype, comptype, dsttype); 113 } 114 115 public MaskFill(long pNativePrim, 116 SurfaceType srctype, 117 CompositeType comptype, 118 SurfaceType dsttype) 119 { 120 super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype); 121 } 122 123 /** 124 * All MaskFill implementors must have this invoker method 125 */ 126 public native void MaskFill(SunGraphics2D sg2d, SurfaceData sData, 127 Composite comp, 128 int x, int y, int w, int h, 129 byte[] mask, int maskoff, int maskscan); 130 131 public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData, 132 Composite comp, 133 double x, double y, 134 double dx1, double dy1, 135 double dx2, double dy2); 136 137 public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData, 138 Composite comp, 139 double x, double y, 140 double dx1, double dy1, 141 double dx2, double dy2, 142 double lw1, double lw2); 143 144 public boolean canDoParallelograms() { 145 return (getNativePrim() != 0); 146 } 147 148 static { 149 GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null)); 150 } 151 152 public GraphicsPrimitive makePrimitive(SurfaceType srctype, 153 CompositeType comptype, 154 SurfaceType dsttype) 155 { 156 if (SurfaceType.OpaqueColor.equals(srctype) || 157 SurfaceType.AnyColor.equals(srctype)) 158 { 159 if (CompositeType.Xor.equals(comptype)) { 160 throw new InternalError("Cannot construct MaskFill for " + 161 "XOR mode"); 162 } else { 163 return new General(srctype, comptype, dsttype); 164 } 165 } else { 166 throw new InternalError("MaskFill can only fill with colors"); 167 } 168 } 169 170 private static class General extends MaskFill { 171 FillRect fillop; 172 MaskBlit maskop; 173 174 public General(SurfaceType srctype, 175 CompositeType comptype, 176 SurfaceType dsttype) 177 { 178 super(srctype, comptype, dsttype); 179 fillop = FillRect.locate(srctype, 180 CompositeType.SrcNoEa, 181 SurfaceType.IntArgb); 182 maskop = MaskBlit.locate(SurfaceType.IntArgb, comptype, dsttype); 183 } 184 185 public void MaskFill(SunGraphics2D sg2d, 186 SurfaceData sData, 187 Composite comp, 188 int x, int y, int w, int h, 189 byte mask[], int offset, int scan) 190 { 191 BufferedImage dstBI = 192 new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 193 SurfaceData tmpData = BufImgSurfaceData.createData(dstBI); 194 195 // REMIND: This is not pretty. It would be nicer if we 196 // passed a "FillData" object to the Pixel loops, instead 197 // of a SunGraphics2D parameter... 198 Region clip = sg2d.clipRegion; 199 sg2d.clipRegion = null; 200 int pixel = sg2d.pixel; 201 sg2d.pixel = tmpData.pixelFor(sg2d.getColor()); 202 fillop.FillRect(sg2d, tmpData, 0, 0, w, h); 203 sg2d.pixel = pixel; 204 sg2d.clipRegion = clip; 205 206 maskop.MaskBlit(tmpData, sData, comp, null, 207 0, 0, x, y, w, h, 208 mask, offset, scan); 209 } 210 } 211 212 public GraphicsPrimitive traceWrap() { 213 return new TraceMaskFill(this); 214 } 215 216 private static class TraceMaskFill extends MaskFill { 217 MaskFill target; 218 MaskFill fillPgramTarget; 219 MaskFill drawPgramTarget; 220 221 public TraceMaskFill(MaskFill target) { 222 super(target.getSourceType(), 223 target.getCompositeType(), 224 target.getDestType()); 225 this.target = target; 226 this.fillPgramTarget = new MaskFill(fillPgramSignature, 227 target.getSourceType(), 228 target.getCompositeType(), 229 target.getDestType()); 230 this.drawPgramTarget = new MaskFill(drawPgramSignature, 231 target.getSourceType(), 232 target.getCompositeType(), 233 target.getDestType()); 234 } 235 236 public GraphicsPrimitive traceWrap() { 237 return this; 238 } 239 240 public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, 241 Composite comp, 242 int x, int y, int w, int h, 243 byte[] mask, int maskoff, int maskscan) 244 { 245 tracePrimitive(target); 246 target.MaskFill(sg2d, sData, comp, x, y, w, h, 247 mask, maskoff, maskscan); 248 } 249 250 public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData, 251 Composite comp, 252 double x, double y, 253 double dx1, double dy1, 254 double dx2, double dy2) 255 { 256 tracePrimitive(fillPgramTarget); 257 target.FillAAPgram(sg2d, sData, comp, 258 x, y, dx1, dy1, dx2, dy2); 259 } 260 261 public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData, 262 Composite comp, 263 double x, double y, 264 double dx1, double dy1, 265 double dx2, double dy2, 266 double lw1, double lw2) 267 { 268 tracePrimitive(drawPgramTarget); 269 target.DrawAAPgram(sg2d, sData, comp, 270 x, y, dx1, dy1, dx2, dy2, lw1, lw2); 271 } 272 273 public boolean canDoParallelograms() { 274 return target.canDoParallelograms(); 275 } 276 } 277 }