NinePatch.java revision f296dca95f09be9832b5dcc79717986525d2b6cb
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    /**
40     * @hide
41     */
42    public final byte[] mChunk;
43    private Paint mPaint;
44    private String mSrcName;  // Useful for debugging
45
46    /**
47     * Create a drawable projection from a bitmap to nine patches.
48     *
49     * @param bitmap    The bitmap describing the patches.
50     * @param chunk     The 9-patch data chunk describing how the underlying
51     *                  bitmap is split apart and drawn.
52     */
53    public NinePatch(Bitmap bitmap, byte[] chunk) {
54        this(bitmap, chunk, null);
55    }
56
57    /**
58     * Create a drawable projection from a bitmap to nine patches.
59     *
60     * @param bitmap    The bitmap describing the patches.
61     * @param chunk     The 9-patch data chunk describing how the underlying
62     *                  bitmap is split apart and drawn.
63     * @param srcName   The name of the source for the bitmap. Might be null.
64     */
65    public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) {
66        mBitmap = bitmap;
67        mChunk = chunk;
68        mSrcName = srcName;
69        validateNinePatchChunk(mBitmap.ni(), chunk);
70    }
71
72    /**
73     * @hide
74     */
75    public NinePatch(NinePatch patch) {
76        mBitmap = patch.mBitmap;
77        mChunk = patch.mChunk;
78        mSrcName = patch.mSrcName;
79        if (patch.mPaint != null) {
80            mPaint = new Paint(patch.mPaint);
81        }
82        validateNinePatchChunk(mBitmap.ni(), mChunk);
83    }
84
85    public void setPaint(Paint p) {
86        mPaint = p;
87    }
88
89    /**
90     * @hide
91     */
92    public Bitmap getBitmap() {
93        return mBitmap;
94    }
95
96    /**
97     * Draw a bitmap of nine patches.
98     *
99     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
100     * @param location  Where to draw the bitmap.
101     */
102    public void draw(Canvas canvas, RectF location) {
103        canvas.drawPatch(this, location, mPaint);
104    }
105
106    /**
107     * Draw a bitmap of nine patches.
108     *
109     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
110     * @param location  Where to draw the bitmap.
111     */
112    public void draw(Canvas canvas, Rect location) {
113        canvas.drawPatch(this, location, mPaint);
114    }
115
116    /**
117     * Draw a bitmap of nine patches.
118     *
119     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
120     * @param location  Where to draw the bitmap.
121     * @param paint     The Paint to draw through.
122     */
123    public void draw(Canvas canvas, Rect location, Paint paint) {
124        canvas.drawPatch(this, location, paint);
125    }
126
127    /**
128     * @hide
129     */
130    void drawSoftware(Canvas canvas, RectF location, Paint paint) {
131        nativeDraw(canvas.mNativeCanvas, location, mBitmap.ni(), mChunk,
132                paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity);
133    }
134
135    /**
136     * @hide
137     */
138    void drawSoftware(Canvas canvas, Rect location, Paint paint) {
139        nativeDraw(canvas.mNativeCanvas, location, mBitmap.ni(), mChunk,
140                paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity);
141    }
142
143    /**
144     * Return the underlying bitmap's density, as per
145     * {@link Bitmap#getDensity() Bitmap.getDensity()}.
146     */
147    public int getDensity() {
148        return mBitmap.mDensity;
149    }
150
151    public int getWidth() {
152        return mBitmap.getWidth();
153    }
154
155    public int getHeight() {
156        return mBitmap.getHeight();
157    }
158
159    public final boolean hasAlpha() {
160        return mBitmap.hasAlpha();
161    }
162
163    public final Region getTransparentRegion(Rect location) {
164        int r = nativeGetTransparentRegion(mBitmap.ni(), mChunk, location);
165        return r != 0 ? new Region(r) : null;
166    }
167
168    public native static boolean isNinePatchChunk(byte[] chunk);
169
170    private static native void validateNinePatchChunk(int bitmap, byte[] chunk);
171    private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
172                                          byte[] c, int paint_instance_or_null,
173                                          int destDensity, int srcDensity);
174    private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
175                                          byte[] c, int paint_instance_or_null,
176                                          int destDensity, int srcDensity);
177    private static native int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location);
178}
179