1/* 2 * Copyright (C) 2006 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 19 20/** 21 * The NinePatch class permits drawing a bitmap in nine sections. 22 * The four corners are unscaled; the four edges are scaled in one axis, 23 * and the middle is scaled in both axes. Normally, the middle is 24 * transparent so that the patch can provide a selection about a rectangle. 25 * Essentially, it allows the creation of custom graphics that will scale the 26 * way that you define, when content added within the image exceeds the normal 27 * bounds of the graphic. For a thorough explanation of a NinePatch image, 28 * read the discussion in the 29 * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D 30 * Graphics</a> document. 31 * <p> 32 * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> 33 * tool offers an extremely handy way to create your NinePatch images, 34 * using a WYSIWYG graphics editor. 35 * </p> 36 */ 37public class NinePatch { 38 private final Bitmap mBitmap; 39 private final byte[] mChunk; 40 private Paint mPaint; 41 private String mSrcName; // Useful for debugging 42 private final RectF mRect = new RectF(); 43 44 /** 45 * Create a drawable projection from a bitmap to nine patches. 46 * 47 * @param bitmap The bitmap describing the patches. 48 * @param chunk The 9-patch data chunk describing how the underlying 49 * bitmap is split apart and drawn. 50 * @param srcName The name of the source for the bitmap. Might be null. 51 */ 52 public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) { 53 mBitmap = bitmap; 54 mChunk = chunk; 55 mSrcName = srcName; 56 validateNinePatchChunk(mBitmap.ni(), chunk); 57 } 58 59 /** 60 * @hide 61 */ 62 public NinePatch(NinePatch patch) { 63 mBitmap = patch.mBitmap; 64 mChunk = patch.mChunk; 65 mSrcName = patch.mSrcName; 66 if (patch.mPaint != null) { 67 mPaint = new Paint(patch.mPaint); 68 } 69 validateNinePatchChunk(mBitmap.ni(), mChunk); 70 } 71 72 public void setPaint(Paint p) { 73 mPaint = p; 74 } 75 76 /** 77 * Draw a bitmap of nine patches. 78 * 79 * @param canvas A container for the current matrix and clip used to draw the bitmap. 80 * @param location Where to draw the bitmap. 81 */ 82 public void draw(Canvas canvas, RectF location) { 83 if (!canvas.isHardwareAccelerated()) { 84 nativeDraw(canvas.mNativeCanvas, location, 85 mBitmap.ni(), mChunk, 86 mPaint != null ? mPaint.mNativePaint : 0, 87 canvas.mDensity, mBitmap.mDensity); 88 } else { 89 canvas.drawPatch(mBitmap, mChunk, location, mPaint); 90 } 91 } 92 93 /** 94 * Draw a bitmap of nine patches. 95 * 96 * @param canvas A container for the current matrix and clip used to draw the bitmap. 97 * @param location Where to draw the bitmap. 98 */ 99 public void draw(Canvas canvas, Rect location) { 100 if (!canvas.isHardwareAccelerated()) { 101 nativeDraw(canvas.mNativeCanvas, location, 102 mBitmap.ni(), mChunk, 103 mPaint != null ? mPaint.mNativePaint : 0, 104 canvas.mDensity, mBitmap.mDensity); 105 } else { 106 mRect.set(location); 107 canvas.drawPatch(mBitmap, mChunk, mRect, mPaint); 108 } 109 } 110 111 /** 112 * Draw a bitmap of nine patches. 113 * 114 * @param canvas A container for the current matrix and clip used to draw the bitmap. 115 * @param location Where to draw the bitmap. 116 * @param paint The Paint to draw through. 117 */ 118 public void draw(Canvas canvas, Rect location, Paint paint) { 119 if (!canvas.isHardwareAccelerated()) { 120 nativeDraw(canvas.mNativeCanvas, location, 121 mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0, 122 canvas.mDensity, mBitmap.mDensity); 123 } else { 124 mRect.set(location); 125 canvas.drawPatch(mBitmap, mChunk, mRect, paint); 126 } 127 } 128 129 /** 130 * Return the underlying bitmap's density, as per 131 * {@link Bitmap#getDensity() Bitmap.getDensity()}. 132 */ 133 public int getDensity() { 134 return mBitmap.mDensity; 135 } 136 137 public int getWidth() { 138 return mBitmap.getWidth(); 139 } 140 141 public int getHeight() { 142 return mBitmap.getHeight(); 143 } 144 145 public final boolean hasAlpha() { 146 return mBitmap.hasAlpha(); 147 } 148 149 public final Region getTransparentRegion(Rect location) { 150 int r = nativeGetTransparentRegion(mBitmap.ni(), mChunk, location); 151 return r != 0 ? new Region(r) : null; 152 } 153 154 public native static boolean isNinePatchChunk(byte[] chunk); 155 156 private static native void validateNinePatchChunk(int bitmap, byte[] chunk); 157 private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance, 158 byte[] c, int paint_instance_or_null, 159 int destDensity, int srcDensity); 160 private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance, 161 byte[] c, int paint_instance_or_null, 162 int destDensity, int srcDensity); 163 private static native int nativeGetTransparentRegion( 164 int bitmap, byte[] chunk, Rect location); 165} 166