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/**
20e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * The NinePatch class permits drawing a bitmap in nine or more sections.
21e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * Essentially, it allows the creation of custom graphics that will scale the
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * way that you define, when content added within the image exceeds the normal
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * bounds of the graphic. For a thorough explanation of a NinePatch image,
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * read the discussion in the
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Graphics</a> document.
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * tool offers an extremely handy way to create your NinePatch images,
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using a WYSIWYG graphics editor.
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class NinePatch {
3447cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    /**
3547cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     * Struct of inset information attached to a 9 patch bitmap.
3647cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     *
3747cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     * Present on a 9 patch bitmap if it optical insets were manually included,
3847cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     * or if outline insets were automatically included by aapt.
3947cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     *
4047cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     * @hide
4147cd8e921db73e894f94ec4729ade90da50996f5Chris Craik     */
4247cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    public static class InsetStruct {
4347cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        @SuppressWarnings({"UnusedDeclaration"}) // called from JNI
4447cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        InsetStruct(int opticalLeft, int opticalTop, int opticalRight, int opticalBottom,
4547cd8e921db73e894f94ec4729ade90da50996f5Chris Craik                int outlineLeft, int outlineTop, int outlineRight, int outlineBottom,
4677b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik                float outlineRadius, int outlineAlpha, float decodeScale) {
4747cd8e921db73e894f94ec4729ade90da50996f5Chris Craik            opticalRect = new Rect(opticalLeft, opticalTop, opticalRight, opticalBottom);
48d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            opticalRect.scale(decodeScale);
4947cd8e921db73e894f94ec4729ade90da50996f5Chris Craik
50d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            outlineRect = scaleInsets(outlineLeft, outlineTop,
51d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets                    outlineRight, outlineBottom, decodeScale);
5247cd8e921db73e894f94ec4729ade90da50996f5Chris Craik
5347cd8e921db73e894f94ec4729ade90da50996f5Chris Craik            this.outlineRadius = outlineRadius * decodeScale;
5477b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik            this.outlineAlpha = outlineAlpha / 255.0f;
5547cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        }
5647cd8e921db73e894f94ec4729ade90da50996f5Chris Craik
5747cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        public final Rect opticalRect;
5847cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        public final Rect outlineRect;
5947cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        public final float outlineRadius;
6077b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik        public final float outlineAlpha;
61d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets
62d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets        /**
63d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets         * Scales up the rect by the given scale, ceiling values, so actual outline Rect
64d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets         * grows toward the inside.
65d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets         */
66d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets        public static Rect scaleInsets(int left, int top, int right, int bottom, float scale) {
67d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            if (scale == 1.0f) {
68d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets                return new Rect(left, top, right, bottom);
69d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            }
70d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets
71d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            Rect result = new Rect();
72d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            result.left = (int) Math.ceil(left * scale);
73d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            result.top = (int) Math.ceil(top * scale);
74d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            result.right = (int) Math.ceil(right * scale);
75d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            result.bottom = (int) Math.ceil(bottom * scale);
76d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets            return  result;
77d253797588f6847d582078bc6a4171e3dc5d8405Sergey Vasilinets        }
7847cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    }
7947cd8e921db73e894f94ec4729ade90da50996f5Chris Craik
80deba785f122a47915756ffd991f5540d952cf937Romain Guy    private final Bitmap mBitmap;
81e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
83e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Used by native code. This pointer is an instance of Res_png_9patch*.
84e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @hide
863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
87ffa84e008c712ceffa09d6b89a49882c88b3cca5Hans Boehm    public long mNativeChunk;
88e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
89deba785f122a47915756ffd991f5540d952cf937Romain Guy    private Paint mPaint;
90e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    private String mSrcName;
91f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy
92f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    /**
93f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     * Create a drawable projection from a bitmap to nine patches.
94f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     *
95e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param bitmap The bitmap describing the patches.
96e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param chunk The 9-patch data chunk describing how the underlying bitmap
97e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *              is split apart and drawn.
98f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     */
99f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    public NinePatch(Bitmap bitmap, byte[] chunk) {
100f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy        this(bitmap, chunk, null);
101f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    }
102f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a drawable projection from a bitmap to nine patches.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
106e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param bitmap The bitmap describing the patches.
107e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param chunk The 9-patch data chunk describing how the underlying
108e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *              bitmap is split apart and drawn.
109e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param srcName The name of the source for the bitmap. Might be null.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBitmap = bitmap;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSrcName = srcName;
1147c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        mNativeChunk = validateNinePatchChunk(chunk);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NinePatch(NinePatch patch) {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBitmap = patch.mBitmap;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSrcName = patch.mSrcName;
12354285f2cbfb6e307d594ca264f7230b4e1e3cdcePhil Dubach        if (patch.mPaint != null) {
12454285f2cbfb6e307d594ca264f7230b4e1e3cdcePhil Dubach            mPaint = new Paint(patch.mPaint);
12554285f2cbfb6e307d594ca264f7230b4e1e3cdcePhil Dubach        }
126e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        // No need to validate the 9patch chunk again, it was done by
127e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        // the instance we're copying from
128e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        mNativeChunk = patch.mNativeChunk;
129e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
130e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
131e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    @Override
132e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    protected void finalize() throws Throwable {
133e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        try {
13401af516a8768cf3c544afb02283c9d8f1dba786cChris Craik            if (mNativeChunk != 0) {
13501af516a8768cf3c544afb02283c9d8f1dba786cChris Craik                // only attempt to destroy correctly initilized chunks
13601af516a8768cf3c544afb02283c9d8f1dba786cChris Craik                nativeFinalize(mNativeChunk);
137ffa84e008c712ceffa09d6b89a49882c88b3cca5Hans Boehm                mNativeChunk = 0;
13801af516a8768cf3c544afb02283c9d8f1dba786cChris Craik            }
139e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        } finally {
140e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy            super.finalize();
141e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
144e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
145e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Returns the name of this NinePatch object if one was specified
146e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * when calling the constructor.
147e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
148e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    public String getName() {
149e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        return mSrcName;
150e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
151e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
152e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
153e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Returns the paint used to draw this NinePatch. The paint can be null.
154e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
155e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @see #setPaint(Paint)
156e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @see #draw(Canvas, Rect)
157e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @see #draw(Canvas, RectF)
158e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
159e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    public Paint getPaint() {
160e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        return mPaint;
161e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
162e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
163e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
164e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Sets the paint to use when drawing the NinePatch.
165e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
166e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param p The paint that will be used to draw this NinePatch.
167e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
168e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @see #getPaint()
169e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @see #draw(Canvas, Rect)
170e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @see #draw(Canvas, RectF)
171e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setPaint(Paint p) {
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaint = p;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
177e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Returns the bitmap used to draw this NinePatch.
1783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public Bitmap getBitmap() {
1803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return mBitmap;
1813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
184e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
186e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param canvas A container for the current matrix and clip used to draw the NinePatch.
187e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param location Where to draw the NinePatch.
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas, RectF location) {
190f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy        canvas.drawPatch(this, location, mPaint);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
192f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
194e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
196e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param canvas A container for the current matrix and clip used to draw the NinePatch.
197e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param location Where to draw the NinePatch.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas, Rect location) {
200f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy        canvas.drawPatch(this, location, mPaint);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
204e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Draws the NinePatch. This method will ignore the paint returned
205e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * by {@link #getPaint()} and use the specified paint instead.
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
207e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param canvas A container for the current matrix and clip used to draw the NinePatch.
208e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param location Where to draw the NinePatch.
209e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param paint The Paint to draw through.
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas, Rect location, Paint paint) {
212f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy        canvas.drawPatch(this, location, paint);
213f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy    }
214f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy
21511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
21611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Return the underlying bitmap's density, as per
21711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * {@link Bitmap#getDensity() Bitmap.getDensity()}.
21811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
21911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getDensity() {
22011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return mBitmap.mDensity;
22111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
222e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
223e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
224e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Returns the intrinsic width, in pixels, of this NinePatch. This is equivalent
225e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * to querying the width of the underlying bitmap returned by {@link #getBitmap()}.
226e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidth() {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBitmap.getWidth();
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
231e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
232e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Returns the intrinsic height, in pixels, of this NinePatch. This is equivalent
233e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * to querying the height of the underlying bitmap returned by {@link #getBitmap()}.
234e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeight() {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBitmap.getHeight();
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
240e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Indicates whether this NinePatch contains transparent or translucent pixels.
241e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * This is equivalent to calling <code>getBitmap().hasAlpha()</code> on this
242e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * NinePatch.
243e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean hasAlpha() {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBitmap.hasAlpha();
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
248e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
249e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Returns a {@link Region} representing the parts of the NinePatch that are
250e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * completely transparent.
251e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
252e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param bounds The location and size of the NinePatch.
253e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
254e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @return null if the NinePatch has no transparent region to
255e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * report, else a {@link Region} holding the parts of the specified bounds
256e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * that are transparent.
257e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
258e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    public final Region getTransparentRegion(Rect bounds) {
2597c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        long r = nativeGetTransparentRegion(mBitmap, mNativeChunk, bounds);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return r != 0 ? new Region(r) : null;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
262e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
263e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
264e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Verifies that the specified byte array is a valid 9-patch data chunk.
265e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
266e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @param chunk A byte array representing a 9-patch data chunk.
267e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *
268e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * @return True if the specified byte array represents a 9-patch data chunk,
269e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     *         false otherwise.
270e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean isNinePatchChunk(byte[] chunk);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
273e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    /**
274e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * Validates the 9-patch chunk and throws an exception if the chunk is invalid.
275e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * If validation is successful, this method returns a native Res_png_9patch*
276e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     * object used by the renderers.
277e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy     */
2787c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    private static native long validateNinePatchChunk(byte[] chunk);
27936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeFinalize(long chunk);
2807c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    private static native long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
282