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