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.Paint;
029: import java.awt.PaintContext;
030: import java.awt.Composite;
031: import java.awt.Rectangle;
032: import java.awt.image.ColorModel;
033: import java.awt.image.BufferedImage;
034: import java.awt.image.WritableRaster;
035: import sun.awt.image.BufImgSurfaceData;
036: import sun.java2d.loops.GraphicsPrimitive;
037: import sun.java2d.SunGraphics2D;
038: import sun.java2d.SurfaceData;
039:
040: /**
041: * MaskFill
042: * 1) fills rectangles of pixels on a surface
043: * 2) performs compositing of colors based upon a Composite
044: * parameter
045: * 3) blends result of composite with destination using an
046: * alpha coverage mask
047: * 4) the mask may be null in which case it should be treated
048: * as if it were an array of all opaque values (0xff)
049: */
050: public class MaskFill extends GraphicsPrimitive {
051: public static final String methodSignature = "MaskFill(...)"
052: .toString();
053:
054: public static final int primTypeID = makePrimTypeID();
055:
056: private static RenderCache fillcache = new RenderCache(10);
057:
058: public static MaskFill locate(SurfaceType srctype,
059: CompositeType comptype, SurfaceType dsttype) {
060: return (MaskFill) GraphicsPrimitiveMgr.locate(primTypeID,
061: srctype, comptype, dsttype);
062: }
063:
064: public static MaskFill locatePrim(SurfaceType srctype,
065: CompositeType comptype, SurfaceType dsttype) {
066: return (MaskFill) GraphicsPrimitiveMgr.locatePrim(primTypeID,
067: srctype, comptype, dsttype);
068: }
069:
070: /*
071: * Note that this uses locatePrim, not locate, so it can return
072: * null if there is no specific loop to handle this op...
073: */
074: public static MaskFill getFromCache(SurfaceType src,
075: CompositeType comp, SurfaceType dst) {
076: Object o = fillcache.get(src, comp, dst);
077: if (o != null) {
078: return (MaskFill) o;
079: }
080: MaskFill fill = locatePrim(src, comp, dst);
081: if (fill != null) {
082: fillcache.put(src, comp, dst, fill);
083: }
084: return fill;
085: }
086:
087: protected MaskFill(SurfaceType srctype, CompositeType comptype,
088: SurfaceType dsttype) {
089: super (methodSignature, primTypeID, srctype, comptype, dsttype);
090: }
091:
092: public MaskFill(long pNativePrim, SurfaceType srctype,
093: CompositeType comptype, SurfaceType dsttype) {
094: super (pNativePrim, methodSignature, primTypeID, srctype,
095: comptype, dsttype);
096: }
097:
098: /**
099: * All MaskFill implementors must have this invoker method
100: */
101: public native void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
102: Composite comp, int x, int y, int w, int h, byte[] mask,
103: int maskoff, int maskscan);
104:
105: static {
106: GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null,
107: null));
108: }
109:
110: public GraphicsPrimitive makePrimitive(SurfaceType srctype,
111: CompositeType comptype, SurfaceType dsttype) {
112: if (SurfaceType.OpaqueColor.equals(srctype)
113: || SurfaceType.AnyColor.equals(srctype)) {
114: if (CompositeType.Xor.equals(comptype)) {
115: throw new InternalError(
116: "Cannot construct MaskFill for " + "XOR mode");
117: } else {
118: return new General(srctype, comptype, dsttype);
119: }
120: } else {
121: throw new InternalError(
122: "MaskFill can only fill with colors");
123: }
124: }
125:
126: private static class General extends MaskFill {
127: FillRect fillop;
128: MaskBlit maskop;
129:
130: public General(SurfaceType srctype, CompositeType comptype,
131: SurfaceType dsttype) {
132: super (srctype, comptype, dsttype);
133: fillop = FillRect.locate(srctype, CompositeType.SrcNoEa,
134: SurfaceType.IntArgb);
135: maskop = MaskBlit.locate(SurfaceType.IntArgb, comptype,
136: dsttype);
137: }
138:
139: public void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
140: Composite comp, int x, int y, int w, int h,
141: byte mask[], int offset, int scan) {
142: BufferedImage dstBI = new BufferedImage(w, h,
143: BufferedImage.TYPE_INT_ARGB);
144: SurfaceData tmpData = BufImgSurfaceData.createData(dstBI);
145:
146: // REMIND: This is not pretty. It would be nicer if we
147: // passed a "FillData" object to the Pixel loops, instead
148: // of a SunGraphics2D parameter...
149: int pixel = sg2d.pixel;
150: sg2d.pixel = tmpData.pixelFor(sg2d.getColor());
151: fillop.FillRect(sg2d, tmpData, 0, 0, w, h);
152: sg2d.pixel = pixel;
153:
154: maskop.MaskBlit(tmpData, sData, comp, null, 0, 0, x, y, w,
155: h, mask, offset, scan);
156: }
157: }
158:
159: public GraphicsPrimitive traceWrap() {
160: return new TraceMaskFill(this );
161: }
162:
163: private static class TraceMaskFill extends MaskFill {
164: MaskFill target;
165:
166: public TraceMaskFill(MaskFill target) {
167: super (target.getSourceType(), target.getCompositeType(),
168: target.getDestType());
169: this .target = target;
170: }
171:
172: public GraphicsPrimitive traceWrap() {
173: return this ;
174: }
175:
176: public void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
177: Composite comp, int x, int y, int w, int h,
178: byte[] mask, int maskoff, int maskscan) {
179: tracePrimitive(target);
180: target.MaskFill(sg2d, sData, comp, x, y, w, h, mask,
181: maskoff, maskscan);
182: }
183: }
184: }
|