This change allows us to use drawables that match the current screen density even when being loaded in compatibility mode. In this case, the bitmap is loaded in the screen density, and the bitmap and nine-patch drawables take care of accounting for the density difference. This should be safe for existing applications, for the most part, since they shouldn't really be pulling the bitmap out of the drawable. For the small rare chance of them breaking, it worth getting the correct graphics. Also this will only happen when there is actually a resource of the matching density, and no existing apps should have resources for anything besides the default density (though of course all of the framework resources will be available in the native density). As part of this, the bitmap density API has been changed to a single integer provider the DPI unit density.
151 lines
5.4 KiB
Java
151 lines
5.4 KiB
Java
/*
|
|
* Copyright (C) 2006 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.graphics;
|
|
|
|
|
|
/**
|
|
* The NinePatch class permits drawing a bitmap in nine sections.
|
|
* The four corners are unscaled; the four edges are scaled in one axis,
|
|
* and the middle is scaled in both axes. Normally, the middle is
|
|
* transparent so that the patch can provide a selection about a rectangle.
|
|
* Essentially, it allows the creation of custom graphics that will scale the
|
|
* way that you define, when content added within the image exceeds the normal
|
|
* bounds of the graphic. For a thorough explanation of a NinePatch image,
|
|
* read the discussion in the
|
|
* <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D
|
|
* Graphics</a> document.
|
|
* <p>
|
|
* The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a>
|
|
* tool offers an extremely handy way to create your NinePatch images,
|
|
* using a WYSIWYG graphics editor.
|
|
* </p>
|
|
*/
|
|
public class NinePatch {
|
|
/**
|
|
* Create a drawable projection from a bitmap to nine patches.
|
|
*
|
|
* @param bitmap The bitmap describing the patches.
|
|
* @param chunk The 9-patch data chunk describing how the underlying
|
|
* bitmap is split apart and drawn.
|
|
* @param srcName The name of the source for the bitmap. Might be null.
|
|
*/
|
|
public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) {
|
|
mBitmap = bitmap;
|
|
mChunk = chunk;
|
|
mSrcName = srcName;
|
|
validateNinePatchChunk(mBitmap.ni(), chunk);
|
|
}
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
public NinePatch(NinePatch patch) {
|
|
mBitmap = patch.mBitmap;
|
|
mChunk = patch.mChunk;
|
|
mSrcName = patch.mSrcName;
|
|
if (patch.mPaint != null) {
|
|
mPaint = new Paint(patch.mPaint);
|
|
}
|
|
validateNinePatchChunk(mBitmap.ni(), mChunk);
|
|
}
|
|
|
|
public void setPaint(Paint p) {
|
|
mPaint = p;
|
|
}
|
|
|
|
/**
|
|
* Draw a bitmap of nine patches.
|
|
*
|
|
* @param canvas A container for the current matrix and clip used to draw the bitmap.
|
|
* @param location Where to draw the bitmap.
|
|
*/
|
|
public void draw(Canvas canvas, RectF location) {
|
|
nativeDraw(canvas.mNativeCanvas, location,
|
|
mBitmap.ni(), mChunk,
|
|
mPaint != null ? mPaint.mNativePaint : 0,
|
|
canvas.mDensity, mBitmap.mDensity);
|
|
}
|
|
|
|
/**
|
|
* Draw a bitmap of nine patches.
|
|
*
|
|
* @param canvas A container for the current matrix and clip used to draw the bitmap.
|
|
* @param location Where to draw the bitmap.
|
|
*/
|
|
public void draw(Canvas canvas, Rect location) {
|
|
nativeDraw(canvas.mNativeCanvas, location,
|
|
mBitmap.ni(), mChunk,
|
|
mPaint != null ? mPaint.mNativePaint : 0,
|
|
canvas.mDensity, mBitmap.mDensity);
|
|
}
|
|
|
|
/**
|
|
* Draw a bitmap of nine patches.
|
|
*
|
|
* @param canvas A container for the current matrix and clip used to draw the bitmap.
|
|
* @param location Where to draw the bitmap.
|
|
* @param paint The Paint to draw through.
|
|
*/
|
|
public void draw(Canvas canvas, Rect location, Paint paint) {
|
|
nativeDraw(canvas.mNativeCanvas, location,
|
|
mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0,
|
|
canvas.mDensity, mBitmap.mDensity);
|
|
}
|
|
|
|
/**
|
|
* Return the underlying bitmap's density, as per
|
|
* {@link Bitmap#getDensity() Bitmap.getDensity()}.
|
|
*/
|
|
public int getDensity() {
|
|
return mBitmap.mDensity;
|
|
}
|
|
|
|
public int getWidth() {
|
|
return mBitmap.getWidth();
|
|
}
|
|
|
|
public int getHeight() {
|
|
return mBitmap.getHeight();
|
|
}
|
|
|
|
public final boolean hasAlpha() {
|
|
return mBitmap.hasAlpha();
|
|
}
|
|
|
|
public final Region getTransparentRegion(Rect location) {
|
|
int r = nativeGetTransparentRegion(mBitmap.ni(), mChunk, location);
|
|
return r != 0 ? new Region(r) : null;
|
|
}
|
|
|
|
public native static boolean isNinePatchChunk(byte[] chunk);
|
|
|
|
private final Bitmap mBitmap;
|
|
private final byte[] mChunk;
|
|
private Paint mPaint;
|
|
private String mSrcName; // Useful for debugging
|
|
|
|
private static native void validateNinePatchChunk(int bitmap, byte[] chunk);
|
|
private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
|
|
byte[] c, int paint_instance_or_null,
|
|
int destDensity, int srcDensity);
|
|
private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
|
|
byte[] c, int paint_instance_or_null,
|
|
int destDensity, int srcDensity);
|
|
private static native int nativeGetTransparentRegion(
|
|
int bitmap, byte[] chunk, Rect location);
|
|
}
|