1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17/**
18 * @author Igor V. Stolyarov
19 * @version $Revision$
20 * Created on 26.11.2005
21 *
22 */
23package org.apache.harmony.awt.gl.render;
24
25import java.awt.AlphaComposite;
26import java.awt.Color;
27import java.awt.Composite;
28import java.awt.geom.AffineTransform;
29import java.awt.image.BufferedImage;
30
31import org.apache.harmony.awt.gl.ImageSurface;
32import org.apache.harmony.awt.gl.MultiRectArea;
33import org.apache.harmony.awt.gl.Surface;
34import org.apache.harmony.awt.gl.XORComposite;
35
36/**
37 * This kind of blitters is intended for drawing one image on the buffered
38 * or volatile image. For the moment we can blit natively Buffered Images which
39 * have sRGB, Linear_RGB, Linear_Gray Color Space and type different
40 * from BufferedImage.TYPE_CUSTOM, Volatile Images and Images which received
41 * using Toolkit and Component classes.
42 */
43public class NativeImageBlitter implements Blitter {
44
45
46    final static NativeImageBlitter inst = new NativeImageBlitter();
47
48    public static NativeImageBlitter getInstance(){
49        return inst;
50    }
51
52    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
53            Surface dstSurf, int width, int height, AffineTransform sysxform,
54            AffineTransform xform, Composite comp, Color bgcolor,
55            MultiRectArea clip) {
56
57        if(!srcSurf.isNativeDrawable()){
58            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
59                    sysxform, xform, comp, bgcolor, clip);
60        }else{
61            if(xform == null){
62                blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
63                        sysxform, comp, bgcolor, clip);
64            }else{
65                double scaleX = xform.getScaleX();
66                double scaleY = xform.getScaleY();
67                double scaledX = dstX / scaleX;
68                double scaledY = dstY / scaleY;
69                AffineTransform at = new AffineTransform();
70                at.setToTranslation(scaledX, scaledY);
71                xform.concatenate(at);
72                sysxform.concatenate(xform);
73                blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
74                        sysxform, comp, bgcolor, clip);
75            }
76        }
77    }
78
79    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
80            Surface dstSurf, int width, int height, AffineTransform sysxform,
81            Composite comp, Color bgcolor, MultiRectArea clip) {
82
83        if(!srcSurf.isNativeDrawable()){
84            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
85                    sysxform, comp, bgcolor, clip);
86        }else{
87            int type = sysxform.getType();
88            switch(type){
89                case AffineTransform.TYPE_TRANSLATION:
90                    dstX += sysxform.getTranslateX();
91                    dstY += sysxform.getTranslateY();
92                case AffineTransform.TYPE_IDENTITY:
93                    blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
94                            width, height, comp, bgcolor, clip);
95                    break;
96                default:
97                    // TODO Need to realize Affine Transformation
98                    if(srcSurf instanceof ImageSurface){
99                        JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY,
100                                dstSurf, width, height,
101                                sysxform, comp, bgcolor, clip);
102                    }else{
103                        int w = srcSurf.getWidth();
104                        int h = srcSurf.getHeight();
105                        BufferedImage tmp = new BufferedImage(w, h,
106                                BufferedImage.TYPE_INT_RGB);
107                        Surface tmpSurf = Surface.getImageSurface(tmp);
108                        blit(0, 0, srcSurf, 0, 0, tmpSurf,
109                                w, h, AlphaComposite.SrcOver, null, null);
110                        JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY,
111                                dstSurf, width, height,
112                                sysxform, comp, bgcolor, clip);
113                    }
114            }
115        }
116    }
117
118    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
119            Surface dstSurf, int width, int height, Composite comp,
120            Color bgcolor, MultiRectArea clip) {
121
122        if(!srcSurf.isNativeDrawable()){
123            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
124                    comp, bgcolor, clip);
125        }else{
126            long dstSurfStruct = dstSurf.getSurfaceDataPtr();
127            Object dstData = dstSurf.getData();
128            int clipRects[];
129            if(clip != null){
130                clipRects = clip.rect;
131            }else{
132                clipRects = new int[]{5, 0, 0, dstSurf.getWidth(),
133                        dstSurf.getHeight()};
134            }
135
136            if(!(srcSurf instanceof ImageSurface)){
137                srcSurf = srcSurf.getImageSurface();
138                if(bgcolor != null){
139                    bgcolor = null;
140                }
141            }
142
143            long srcSurfStruct = srcSurf.getSurfaceDataPtr();
144            Object srcData = srcSurf.getData();
145            if(comp instanceof AlphaComposite){
146                AlphaComposite ac = (AlphaComposite) comp;
147                int compType = ac.getRule();
148                float alpha = ac.getAlpha();
149                if(bgcolor != null){
150                    bltBG(srcX, srcY, srcSurfStruct, srcData,
151                            dstX, dstY, dstSurfStruct, dstData,
152                            width, height, bgcolor.getRGB(),
153                            compType, alpha, clipRects, srcSurf.invalidated());
154                    dstSurf.invalidate();
155                    srcSurf.validate();
156                }else{
157                    blt(srcX, srcY, srcSurfStruct, srcData,
158                            dstX, dstY, dstSurfStruct, dstData,
159                            width, height, compType, alpha,
160                            clipRects, srcSurf.invalidated());
161                    dstSurf.invalidate();
162                    srcSurf.validate();
163                }
164            }else if(comp instanceof XORComposite){
165                XORComposite xcomp = (XORComposite) comp;
166                xor(srcX, srcY, srcSurfStruct, srcData,
167                        dstX, dstY, dstSurfStruct, dstData,
168                        width, height, xcomp.getXORColor().getRGB(),
169                        clipRects, srcSurf.invalidated());
170                dstSurf.invalidate();
171                srcSurf.validate();
172            }else{
173                if(srcSurf instanceof ImageSurface){
174                    JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY,
175                            dstSurf, width, height,
176                            comp, bgcolor, clip);
177                }else{
178                    int w = srcSurf.getWidth();
179                    int h = srcSurf.getHeight();
180                    BufferedImage tmp = new BufferedImage(w, h,
181                            BufferedImage.TYPE_INT_RGB);
182                    Surface tmpSurf = Surface.getImageSurface(tmp);
183                    long tmpSurfStruct = tmpSurf.getSurfaceDataPtr();
184                    Object tmpData = tmpSurf.getData();
185                    int tmpClip[] = new int[]{5, 0, 0, srcSurf.getWidth(),
186                            srcSurf.getHeight()};
187
188                    blt(0, 0, srcSurfStruct, srcData, 0, 0,
189                            tmpSurfStruct, tmpData, w, h,
190                            AlphaComposite.SRC_OVER,
191                            1.0f, tmpClip, srcSurf.invalidated());
192                    srcSurf.validate();
193                    JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY,
194                            dstSurf, width, height,
195                            comp, bgcolor, clip);
196                }
197            }
198        }
199
200    }
201
202    private native void bltBG(int srcX, int srcY, long srsSurfDataPtr,
203            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
204            Object dstData, int width, int height, int bgcolor,
205            int compType, float alpha, int clip[], boolean invalidated);
206
207    private native void blt(int srcX, int srcY, long srsSurfDataPtr,
208            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
209            Object dstData, int width, int height, int compType,
210            float alpha, int clip[], boolean invalidated);
211
212    private native void xor(int srcX, int srcY, long srsSurfDataPtr,
213            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
214            Object dstData, int width, int height, int xorcolor,
215            int clip[], boolean invalidated);
216
217
218}
219