Home | History | Annotate | Download | only in graphics
      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 
     17 package 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  */
     37 public 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