NinePatch.java revision f296dca95f09be9832b5dcc79717986525d2b6cb
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The NinePatch class permits drawing a bitmap in nine sections. 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The four corners are unscaled; the four edges are scaled in one axis, 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the middle is scaled in both axes. Normally, the middle is 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transparent so that the patch can provide a selection about a rectangle. 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Essentially, it allows the creation of custom graphics that will scale the 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * way that you define, when content added within the image exceeds the normal 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * bounds of the graphic. For a thorough explanation of a NinePatch image, 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * read the discussion in the 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Graphics</a> document. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * tool offers an extremely handy way to create your NinePatch images, 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using a WYSIWYG graphics editor. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class NinePatch { 38deba785f122a47915756ffd991f5540d952cf937Romain Guy private final Bitmap mBitmap; 393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy /** 403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * @hide 413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy public final byte[] mChunk; 43deba785f122a47915756ffd991f5540d952cf937Romain Guy private Paint mPaint; 44deba785f122a47915756ffd991f5540d952cf937Romain Guy private String mSrcName; // Useful for debugging 45f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy 46f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy /** 47f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy * Create a drawable projection from a bitmap to nine patches. 48f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy * 49f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy * @param bitmap The bitmap describing the patches. 50f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy * @param chunk The 9-patch data chunk describing how the underlying 51f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy * bitmap is split apart and drawn. 52f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy */ 53f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy public NinePatch(Bitmap bitmap, byte[] chunk) { 54f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy this(bitmap, chunk, null); 55f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy } 56f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a drawable projection from a bitmap to nine patches. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bitmap The bitmap describing the patches. 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param chunk The 9-patch data chunk describing how the underlying 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * bitmap is split apart and drawn. 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param srcName The name of the source for the bitmap. Might be null. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmap = bitmap; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChunk = chunk; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSrcName = srcName; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateNinePatchChunk(mBitmap.ni(), chunk); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public NinePatch(NinePatch patch) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBitmap = patch.mBitmap; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChunk = patch.mChunk; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSrcName = patch.mSrcName; 7954285f2cbfb6e307d594ca264f7230b4e1e3cdcePhil Dubach if (patch.mPaint != null) { 8054285f2cbfb6e307d594ca264f7230b4e1e3cdcePhil Dubach mPaint = new Paint(patch.mPaint); 8154285f2cbfb6e307d594ca264f7230b4e1e3cdcePhil Dubach } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateNinePatchChunk(mBitmap.ni(), mChunk); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPaint(Paint p) { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPaint = p; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy /** 903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * @hide 913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy public Bitmap getBitmap() { 933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return mBitmap; 943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Draw a bitmap of nine patches. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param canvas A container for the current matrix and clip used to draw the bitmap. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param location Where to draw the bitmap. 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas, RectF location) { 103f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy canvas.drawPatch(this, location, mPaint); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 105f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Draw a bitmap of nine patches. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param canvas A container for the current matrix and clip used to draw the bitmap. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param location Where to draw the bitmap. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas, Rect location) { 113f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy canvas.drawPatch(this, location, mPaint); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Draw a bitmap of nine patches. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param canvas A container for the current matrix and clip used to draw the bitmap. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param location Where to draw the bitmap. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param paint The Paint to draw through. 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas, Rect location, Paint paint) { 124f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy canvas.drawPatch(this, location, paint); 125f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy } 126f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy 127f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy /** 128f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy * @hide 129f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy */ 130f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy void drawSoftware(Canvas canvas, RectF location, Paint paint) { 131f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy nativeDraw(canvas.mNativeCanvas, location, mBitmap.ni(), mChunk, 132f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity); 133f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy } 134f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy 135f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy /** 136f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy * @hide 137f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy */ 138f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy void drawSoftware(Canvas canvas, Rect location, Paint paint) { 139f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy nativeDraw(canvas.mNativeCanvas, location, mBitmap.ni(), mChunk, 140f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn /** 14411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * Return the underlying bitmap's density, as per 14511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn * {@link Bitmap#getDensity() Bitmap.getDensity()}. 14611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn */ 14711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn public int getDensity() { 14811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn return mBitmap.mDensity; 14911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn } 15011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidth() { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmap.getWidth(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmap.getHeight(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean hasAlpha() { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBitmap.hasAlpha(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Region getTransparentRegion(Rect location) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int r = nativeGetTransparentRegion(mBitmap.ni(), mChunk, location); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r != 0 ? new Region(r) : null; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native static boolean isNinePatchChunk(byte[] chunk); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void validateNinePatchChunk(int bitmap, byte[] chunk); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance, 17211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn byte[] c, int paint_instance_or_null, 17311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn int destDensity, int srcDensity); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance, 17511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn byte[] c, int paint_instance_or_null, 17611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn int destDensity, int srcDensity); 177f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy private static native int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 179