Bitmap_Delegate.java revision 2d56b273ef6e2984a4e8914fb67772b173d0a154
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 * @param input the file from which to read the bitmap content 80 * @param isMutable whether the bitmap is mutable 81 * @param density the density associated with the bitmap 82 * 83 * @see Bitmap#isMutable() 84 * @see Bitmap#getDensity() 85 */ 86 public static Bitmap createBitmap(File input, boolean isMutable, Density density) 87 throws IOException { 88 // create a delegate with the content of the file. 89 Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input)); 90 91 return createBitmap(delegate, isMutable, density.getValue()); 92 } 93 94 /** 95 * Creates and returns a {@link Bitmap} initialized with the given stream content. 96 * 97 * @param input the stream from which to read the bitmap content 98 * @param isMutable whether the bitmap is mutable 99 * @param density the density associated with the bitmap 100 * 101 * @see Bitmap#isMutable() 102 * @see Bitmap#getDensity() 103 */ 104 public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density) 105 throws IOException { 106 // create a delegate with the content of the stream. 107 Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input)); 108 109 return createBitmap(delegate, isMutable, density.getValue()); 110 } 111 112 /** 113 * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage} 114 * 115 * @param image the bitmap content 116 * @param isMutable whether the bitmap is mutable 117 * @param density the density associated with the bitmap 118 * 119 * @see Bitmap#isMutable() 120 * @see Bitmap#getDensity() 121 */ 122 public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) 123 throws IOException { 124 // create a delegate with the given image. 125 Bitmap_Delegate delegate = new Bitmap_Delegate(image); 126 127 return createBitmap(delegate, isMutable, density.getValue()); 128 } 129 130 /** 131 * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}. 132 */ 133 public static BufferedImage getImage(Bitmap bitmap) { 134 // get the delegate from the native int. 135 Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap); 136 if (delegate == null) { 137 assert false; 138 return null; 139 } 140 141 return delegate.mImage; 142 } 143 144 public static int getBufferedImageType(int nativeBitmapConfig) { 145 switch (Config.sConfigs[nativeBitmapConfig]) { 146 case ALPHA_8: 147 return BufferedImage.TYPE_INT_ARGB; 148 case RGB_565: 149 return BufferedImage.TYPE_INT_ARGB; 150 case ARGB_4444: 151 return BufferedImage.TYPE_INT_ARGB; 152 case ARGB_8888: 153 return BufferedImage.TYPE_INT_ARGB; 154 } 155 156 return BufferedImage.TYPE_INT_ARGB; 157 } 158 159 /** 160 * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}. 161 */ 162 public BufferedImage getImage() { 163 return mImage; 164 } 165 166 // ---- native methods ---- 167 168 /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width, 169 int height, int nativeConfig, boolean mutable) { 170 int imageType = getBufferedImageType(nativeConfig); 171 172 // create the image 173 BufferedImage image = new BufferedImage(width, height, imageType); 174 175 // FIXME fill the bitmap! 176 177 // create a delegate with the content of the stream. 178 Bitmap_Delegate delegate = new Bitmap_Delegate(image); 179 180 return createBitmap(delegate, mutable, Bitmap.getDefaultDensity()); 181 } 182 183 /*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) { 184 // FIXME implement native delegate 185 throw new UnsupportedOperationException("Native delegate needed for Bitmap"); 186 } 187 188 /*package*/ static void nativeDestructor(int nativeBitmap) { 189 sManager.removeDelegate(nativeBitmap); 190 } 191 192 /*package*/ static void nativeRecycle(int nativeBitmap) { 193 sManager.removeDelegate(nativeBitmap); 194 } 195 196 /*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality, 197 OutputStream stream, byte[] tempStorage) { 198 // FIXME implement native delegate 199 throw new UnsupportedOperationException("Native delegate needed for Bitmap"); 200 } 201 202 /*package*/ static void nativeErase(int nativeBitmap, int color) { 203 // get the delegate from the native int. 204 Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 205 if (delegate == null) { 206 assert false; 207 return; 208 } 209 210 BufferedImage image = delegate.mImage; 211 212 Graphics2D g = image.createGraphics(); 213 try { 214 if (delegate.mHasAlpha == false) { 215 color |= color & 0xFF000000; 216 } 217 g.setColor(new java.awt.Color(color)); 218 219 g.fillRect(0, 0, image.getWidth(), image.getHeight()); 220 } finally { 221 g.dispose(); 222 } 223 } 224 225 /*package*/ static int nativeWidth(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 nativeHeight(int nativeBitmap) { 237 // get the delegate from the native int. 238 Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 239 if (delegate == null) { 240 assert false; 241 return 0; 242 } 243 244 return delegate.mImage.getHeight(); 245 } 246 247 /*package*/ static int nativeRowBytes(int nativeBitmap) { 248 // get the delegate from the native int. 249 Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 250 if (delegate == null) { 251 assert false; 252 return 0; 253 } 254 255 return delegate.mImage.getWidth(); 256 } 257 258 /*package*/ static int nativeConfig(int nativeBitmap) { 259 return Config.ARGB_8888.nativeInt; 260 } 261 262 /*package*/ static boolean nativeHasAlpha(int nativeBitmap) { 263 // get the delegate from the native int. 264 Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 265 if (delegate == null) { 266 assert false; 267 return true; 268 } 269 270 return delegate.mHasAlpha; 271 } 272 273 /*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y) { 274 // get the delegate from the native int. 275 Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 276 if (delegate == null) { 277 assert false; 278 return 0; 279 } 280 281 return delegate.mImage.getRGB(x, y); 282 } 283 284 /*package*/ static void nativeGetPixels(int nativeBitmap, int[] pixels, int offset, 285 int stride, int x, int y, int width, int height) { 286 // FIXME implement native delegate 287 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeGetPixels"); 288 } 289 290 291 /*package*/ static void nativeSetPixel(int nativeBitmap, int x, int y, int color) { 292 // FIXME implement native delegate 293 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeSetPixel"); 294 } 295 296 /*package*/ static void nativeSetPixels(int nativeBitmap, int[] colors, int offset, 297 int stride, int x, int y, int width, int height) { 298 // FIXME implement native delegate 299 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeSetPixels"); 300 } 301 302 /*package*/ static void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst) { 303 // FIXME implement native delegate 304 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeCopyPixelsToBuffer"); 305 } 306 307 /*package*/ static void nativeCopyPixelsFromBuffer(int nb, Buffer src) { 308 // FIXME implement native delegate 309 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeCopyPixelsFromBuffer"); 310 } 311 312 /*package*/ static int nativeGenerationId(int nativeBitmap) { 313 // FIXME implement native delegate 314 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeGenerationId"); 315 } 316 317 /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) { 318 // FIXME implement native delegate 319 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeCreateFromParcel"); 320 } 321 322 /*package*/ static boolean nativeWriteToParcel(int nativeBitmap, boolean isMutable, 323 int density, Parcel p) { 324 // FIXME implement native delegate 325 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeWriteToParcel"); 326 } 327 328 /*package*/ static Bitmap nativeExtractAlpha(int nativeBitmap, int nativePaint, 329 int[] offsetXY) { 330 // FIXME implement native delegate 331 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeExtractAlpha"); 332 } 333 334 335 /*package*/ static void nativePrepareToDraw(int nativeBitmap) { 336 // FIXME implement native delegate 337 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativePrepareToDraw"); 338 } 339 340 /*package*/ static void nativeSetHasAlpha(int nativeBitmap, boolean hasAlpha) { 341 // get the delegate from the native int. 342 Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 343 if (delegate == null) { 344 assert false; 345 return; 346 } 347 348 delegate.mHasAlpha = hasAlpha; 349 } 350 351 /*package*/ static boolean nativeSameAs(int nb0, int nb1) { 352 // FIXME implement native delegate 353 throw new UnsupportedOperationException("Native delegate needed for Bitmap.nativeSameAs"); 354 } 355 356 // ---- Private delegate/helper methods ---- 357 358 private Bitmap_Delegate(BufferedImage image) { 359 mImage = image; 360 } 361 362 private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) { 363 // get its native_int 364 int nativeInt = sManager.addDelegate(delegate); 365 366 // and create/return a new Bitmap with it 367 return new Bitmap(nativeInt, isMutable, null /*ninePatchChunk*/, density); 368 } 369} 370