1 /*
2  * Copyright (c) 1997, 2002, 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.pipe;
27 
28 import java.awt.AlphaComposite;
29 import java.awt.CompositeContext;
30 import java.awt.PaintContext;
31 import java.awt.Rectangle;
32 import java.awt.Shape;
33 import java.awt.RenderingHints;
34 import java.awt.image.ColorModel;
35 import java.awt.image.BufferedImage;
36 import java.awt.image.Raster;
37 import java.awt.image.WritableRaster;
38 import sun.awt.image.BufImgSurfaceData;
39 import sun.java2d.SunGraphics2D;
40 import sun.java2d.SurfaceData;
41 import sun.java2d.loops.Blit;
42 import sun.java2d.loops.MaskBlit;
43 import sun.java2d.loops.CompositeType;
44 
45 public class GeneralCompositePipe implements CompositePipe {
46     class TileContext {
47         SunGraphics2D sunG2D;
48         PaintContext paintCtxt;
49         CompositeContext compCtxt;
50         ColorModel compModel;
51         Object pipeState;
52 
TileContext(SunGraphics2D sg, PaintContext pCtx, CompositeContext cCtx, ColorModel cModel)53         public TileContext(SunGraphics2D sg, PaintContext pCtx,
54                            CompositeContext cCtx, ColorModel cModel) {
55             sunG2D = sg;
56             paintCtxt = pCtx;
57             compCtxt = cCtx;
58             compModel = cModel;
59         }
60     }
61 
startSequence(SunGraphics2D sg, Shape s, Rectangle devR, int[] abox)62     public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
63                                 int[] abox) {
64         RenderingHints hints = sg.getRenderingHints();
65         ColorModel model = sg.getDeviceColorModel();
66         PaintContext paintContext =
67             sg.paint.createContext(model, devR, s.getBounds2D(),
68                                    sg.cloneTransform(),
69                                    hints);
70         CompositeContext compositeContext =
71             sg.composite.createContext(paintContext.getColorModel(), model,
72                                        hints);
73         return new TileContext(sg, paintContext, compositeContext, model);
74     }
75 
needTile(Object ctx, int x, int y, int w, int h)76     public boolean needTile(Object ctx, int x, int y, int w, int h) {
77         return true;
78     }
79 
80     /**
81     * GeneralCompositePipe.renderPathTile works with custom composite operator
82     * provided by an application
83     */
renderPathTile(Object ctx, byte[] atile, int offset, int tilesize, int x, int y, int w, int h)84     public void renderPathTile(Object ctx,
85                                byte[] atile, int offset, int tilesize,
86                                int x, int y, int w, int h) {
87         TileContext context = (TileContext) ctx;
88         PaintContext paintCtxt = context.paintCtxt;
89         CompositeContext compCtxt = context.compCtxt;
90         SunGraphics2D sg = context.sunG2D;
91 
92         Raster srcRaster = paintCtxt.getRaster(x, y, w, h);
93         ColorModel paintModel = paintCtxt.getColorModel();
94 
95         Raster dstRaster;
96         Raster dstIn;
97         WritableRaster dstOut;
98 
99         SurfaceData sd = sg.getSurfaceData();
100         dstRaster = sd.getRaster(x, y, w, h);
101         if (dstRaster instanceof WritableRaster && atile == null) {
102             dstOut = (WritableRaster) dstRaster;
103             dstOut = dstOut.createWritableChild(x, y, w, h, 0, 0, null);
104             dstIn = dstOut;
105         } else {
106             dstIn = dstRaster.createChild(x, y, w, h, 0, 0, null);
107             dstOut = dstIn.createCompatibleWritableRaster();
108         }
109 
110         compCtxt.compose(srcRaster, dstIn, dstOut);
111 
112         if (dstRaster != dstOut && dstOut.getParent() != dstRaster) {
113             if (dstRaster instanceof WritableRaster && atile == null) {
114                 ((WritableRaster) dstRaster).setDataElements(x, y, dstOut);
115             } else {
116                 ColorModel cm = sg.getDeviceColorModel();
117                 BufferedImage resImg =
118                     new BufferedImage(cm, dstOut,
119                                       cm.isAlphaPremultiplied(),
120                                       null);
121                 SurfaceData resData = BufImgSurfaceData.createData(resImg);
122                 if (atile == null) {
123                     Blit blit = Blit.getFromCache(resData.getSurfaceType(),
124                                                   CompositeType.SrcNoEa,
125                                                   sd.getSurfaceType());
126                     blit.Blit(resData, sd, AlphaComposite.Src, null,
127                               0, 0, x, y, w, h);
128                 } else {
129                     MaskBlit blit = MaskBlit.getFromCache(resData.getSurfaceType(),
130                                                           CompositeType.SrcNoEa,
131                                                           sd.getSurfaceType());
132                     blit.MaskBlit(resData, sd, AlphaComposite.Src, null,
133                                   0, 0, x, y, w, h,
134                                   atile, offset, tilesize);
135                 }
136             }
137         }
138     }
139 
skipTile(Object ctx, int x, int y)140     public void skipTile(Object ctx, int x, int y) {
141         return;
142     }
143 
endSequence(Object ctx)144     public void endSequence(Object ctx) {
145         TileContext context = (TileContext) ctx;
146         if (context.paintCtxt != null) {
147             context.paintCtxt.dispose();
148         }
149         if (context.compCtxt != null) {
150             context.compCtxt.dispose();
151         }
152     }
153 
154 }
155