Bitmap_Delegate.java revision c2e9651bf386a1f7bf7fc706cf5424950570470c
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
19import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
20import com.android.layoutlib.bridge.impl.DelegateManager;
21
22import android.graphics.Bitmap.Config;
23import android.os.Parcel;
24
25import java.awt.Graphics2D;
26import java.awt.image.BufferedImage;
27import java.io.File;
28import java.io.IOException;
29import java.io.InputStream;
30import java.io.OutputStream;
31import java.nio.Buffer;
32
33import javax.imageio.ImageIO;
34
35/**
36 * Delegate implementing the native methods of android.graphics.Bitmap
37 *
38 * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
39 * by calls to methods of the same name in this delegate class.
40 *
41 * This class behaves like the original native implementation, but in Java, keeping previously
42 * native data into its own objects and mapping them to int that are sent back and forth between
43 * it and the original Bitmap class.
44 *
45 * @see DelegateManager
46 *
47 */
48public class Bitmap_Delegate {
49
50    // ---- delegate manager ----
51    private static final DelegateManager<Bitmap_Delegate> sManager =
52            new DelegateManager<Bitmap_Delegate>();
53
54    // ---- delegate helper data ----
55
56    // ---- delegate data ----
57    private BufferedImage mImage;
58    private boolean mHasAlpha = true;
59
60    // ---- Public Helper methods ----
61
62    /**
63     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
64     */
65    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
66        return sManager.getDelegate(bitmap.mNativeBitmap);
67    }
68
69    /**
70     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
71     */
72    public static Bitmap_Delegate getDelegate(int native_bitmap) {
73        return sManager.getDelegate(native_bitmap);
74    }
75
76    /**
77     * Creates and returns a {@link Bitmap} initialized with the given file content.
78     */
79    public static Bitmap createBitmap(File input, Density density) throws IOException {
80        // create a delegate with the content of the file.
81        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input));
82
83        return createBitmap(delegate, density.getValue());
84    }
85
86    /**
87     * Creates and returns a {@link Bitmap} initialized with the given stream content.
88     */
89    public static Bitmap createBitmap(InputStream input, Density density) throws IOException {
90        // create a delegate with the content of the stream.
91        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input));
92
93        return createBitmap(delegate, density.getValue());
94    }
95
96    /**
97     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
98     */
99    public static Bitmap createBitmap(BufferedImage image, Density density) throws IOException {
100        // create a delegate with the given image.
101        Bitmap_Delegate delegate = new Bitmap_Delegate(image);
102
103        return createBitmap(delegate, density.getValue());
104    }
105
106    /**
107     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
108     */
109    public static BufferedImage getImage(Bitmap bitmap) {
110        // get the delegate from the native int.
111        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
112        if (delegate == null) {
113            assert false;
114            return null;
115        }
116
117        return delegate.mImage;
118    }
119
120    public static int getBufferedImageType(int nativeBitmapConfig) {
121        switch (Config.sConfigs[nativeBitmapConfig]) {
122            case ALPHA_8:
123                return BufferedImage.TYPE_INT_ARGB;
124            case RGB_565:
125                return BufferedImage.TYPE_INT_ARGB;
126            case ARGB_4444:
127                return BufferedImage.TYPE_INT_ARGB;
128            case ARGB_8888:
129                return BufferedImage.TYPE_INT_ARGB;
130        }
131
132        return BufferedImage.TYPE_INT_ARGB;
133    }
134
135    /**
136     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
137     */
138    public BufferedImage getImage() {
139        return mImage;
140    }
141
142    // ---- native methods ----
143
144    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
145            int height, int nativeConfig, boolean mutable) {
146        int imageType = getBufferedImageType(nativeConfig);
147
148        // create the image
149        BufferedImage image = new BufferedImage(width, height, imageType);
150
151        // FIXME fill the bitmap!
152
153        // create a delegate with the content of the stream.
154        Bitmap_Delegate delegate = new Bitmap_Delegate(image);
155
156        return createBitmap(delegate, Bitmap.getDefaultDensity());
157    }
158
159    /*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) {
160        // FIXME implement native delegate
161        throw new UnsupportedOperationException("Native delegate needed for Bitmap");
162    }
163
164    /*package*/ static void nativeDestructor(int nativeBitmap) {
165        // FIXME implement native delegate
166        throw new UnsupportedOperationException("Native delegate needed for Bitmap");
167    }
168
169    /*package*/ static void nativeRecycle(int nativeBitmap) {
170        // FIXME implement native delegate
171        throw new UnsupportedOperationException("Native delegate needed for Bitmap");
172    }
173
174    /*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality,
175            OutputStream stream, byte[] tempStorage) {
176        // FIXME implement native delegate
177        throw new UnsupportedOperationException("Native delegate needed for Bitmap");
178    }
179
180    /*package*/ static void nativeErase(int nativeBitmap, int color) {
181        // get the delegate from the native int.
182        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
183        if (delegate == null) {
184            assert false;
185            return;
186        }
187
188        BufferedImage image = delegate.mImage;
189
190        Graphics2D g = image.createGraphics();
191        try {
192            if (delegate.mHasAlpha == false) {
193                color |= color & 0xFF000000;
194            }
195            g.setColor(new java.awt.Color(color));
196
197            g.fillRect(0, 0, image.getWidth(), image.getHeight());
198        } finally {
199            g.dispose();
200        }
201    }
202
203    /*package*/ static int nativeWidth(int nativeBitmap) {
204        // get the delegate from the native int.
205        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
206        if (delegate == null) {
207            assert false;
208            return 0;
209        }
210
211        return delegate.mImage.getWidth();
212    }
213
214    /*package*/ static int nativeHeight(int nativeBitmap) {
215        // get the delegate from the native int.
216        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
217        if (delegate == null) {
218            assert false;
219            return 0;
220        }
221
222        return delegate.mImage.getHeight();
223    }
224
225    /*package*/ static int nativeRowBytes(int nativeBitmap) {
226        // get the delegate from the native int.
227        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
228        if (delegate == null) {
229            assert false;
230            return 0;
231        }
232
233        return delegate.mImage.getWidth();
234    }
235
236    /*package*/ static int nativeConfig(int nativeBitmap) {
237        return Config.ARGB_8888.nativeInt;
238    }
239
240    /*package*/ static boolean nativeHasAlpha(int nativeBitmap) {
241        // get the delegate from the native int.
242        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
243        if (delegate == null) {
244            assert false;
245            return true;
246        }
247
248        return delegate.mHasAlpha;
249    }
250
251    /*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y) {
252        // get the delegate from the native int.
253        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
254        if (delegate == null) {
255            assert false;
256            return 0;
257        }
258
259        return delegate.mImage.getRGB(x, y);
260    }
261
262    /*package*/ static void nativeGetPixels(int nativeBitmap, int[] pixels, int offset,
263            int stride, int x, int y, int width, int height) {
264        // FIXME implement native delegate
265        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeGetPixels");
266    }
267
268
269    /*package*/ static void nativeSetPixel(int nativeBitmap, int x, int y, int color) {
270        // FIXME implement native delegate
271        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeSetPixel");
272    }
273
274    /*package*/ static void nativeSetPixels(int nativeBitmap, int[] colors, int offset,
275            int stride, int x, int y, int width, int height) {
276        // FIXME implement native delegate
277        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeSetPixels");
278    }
279
280    /*package*/ static void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst) {
281        // FIXME implement native delegate
282        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeCopyPixelsToBuffer");
283    }
284
285    /*package*/ static void nativeCopyPixelsFromBuffer(int nb, Buffer src) {
286        // FIXME implement native delegate
287        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeCopyPixelsFromBuffer");
288    }
289
290    /*package*/ static int nativeGenerationId(int nativeBitmap) {
291        // FIXME implement native delegate
292        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeGenerationId");
293    }
294
295    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
296        // FIXME implement native delegate
297        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeCreateFromParcel");
298    }
299
300    /*package*/ static boolean nativeWriteToParcel(int nativeBitmap, boolean isMutable,
301            int density, Parcel p) {
302        // FIXME implement native delegate
303        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeWriteToParcel");
304    }
305
306    /*package*/ static Bitmap nativeExtractAlpha(int nativeBitmap, int nativePaint,
307            int[] offsetXY) {
308        // FIXME implement native delegate
309        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeExtractAlpha");
310    }
311
312
313    /*package*/ static void nativePrepareToDraw(int nativeBitmap) {
314        // FIXME implement native delegate
315        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativePrepareToDraw");
316    }
317
318    /*package*/ static void nativeSetHasAlpha(int nativeBitmap, boolean hasAlpha) {
319        // get the delegate from the native int.
320        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
321        if (delegate == null) {
322            assert false;
323            return;
324        }
325
326        delegate.mHasAlpha = hasAlpha;
327    }
328
329    /*package*/ static boolean nativeSameAs(int nb0, int nb1) {
330        // FIXME implement native delegate
331        throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeSameAs");
332    }
333
334    // ---- Private delegate/helper methods ----
335
336    private Bitmap_Delegate(BufferedImage image) {
337        mImage = image;
338    }
339
340    private static Bitmap createBitmap(Bitmap_Delegate delegate, int density) {
341        // get its native_int
342        int nativeInt = sManager.addDelegate(delegate);
343
344        // and create/return a new Bitmap with it
345        return new Bitmap(nativeInt, true /*isMutable*/, null /*ninePatchChunk*/, density);
346    }
347}
348