add boundary patch
This commit is contained in:
173
graphics/java/android/graphics/utils/BoundaryPatch.java
Normal file
173
graphics/java/android/graphics/utils/BoundaryPatch.java
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.utils;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.Xfermode;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class BoundaryPatch {
|
||||
private Paint mPaint;
|
||||
private Bitmap mTexture;
|
||||
private int mRows;
|
||||
private int mCols;
|
||||
private float[] mCubicPoints;
|
||||
private boolean mDirty;
|
||||
// these are the computed output of the native code
|
||||
private float[] mVerts;
|
||||
private short[] mIndices;
|
||||
|
||||
public BoundaryPatch() {
|
||||
mRows = mCols = 2; // default minimum
|
||||
mCubicPoints = new float[24];
|
||||
mPaint = new Paint();
|
||||
mPaint.setDither(true);
|
||||
mPaint.setFilterBitmap(true);
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the boundary to be 4 cubics. This takes a single array of floats,
|
||||
* and picks up the 12 pairs starting at offset, and treats them as
|
||||
* the x,y coordinates of the cubic control points. The points wrap around
|
||||
* a patch, as follows. For documentation purposes, pts[i] will mean the
|
||||
* x,y pair of floats, as if pts[] were an array of "points".
|
||||
*
|
||||
* Top: pts[0..3]
|
||||
* Right: pts[3..6]
|
||||
* Bottom: pts[6..9]
|
||||
* Right: pts[9..11], pts[0]
|
||||
*
|
||||
* The coordinates are copied from the input array, so subsequent changes
|
||||
* to pts[] will not be reflected in the boundary.
|
||||
*
|
||||
* @param pts The src array of x,y pairs for the boundary cubics
|
||||
* @param offset The index into pts of the first pair
|
||||
* @param rows The number of points across to approximate the boundary.
|
||||
* Must be >= 2, though very large values may slow down drawing
|
||||
* @param cols The number of points down to approximate the boundary.
|
||||
* Must be >= 2, though very large values may slow down drawing
|
||||
*/
|
||||
public void setCubicBoundary(float[] pts, int offset, int rows, int cols) {
|
||||
if (rows < 2 || cols < 2) {
|
||||
throw new RuntimeException("rows and cols must be >= 2");
|
||||
}
|
||||
System.arraycopy(pts, offset, mCubicPoints, 0, 24);
|
||||
if (mRows != rows || mCols != cols) {
|
||||
mRows = rows;
|
||||
mCols = cols;
|
||||
}
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference a bitmap texture to be mapped onto the patch.
|
||||
*/
|
||||
public void setTexture(Bitmap texture) {
|
||||
if (mTexture != texture) {
|
||||
if (mTexture == null ||
|
||||
mTexture.getWidth() != texture.getWidth() ||
|
||||
mTexture.getHeight() != texture.getHeight()) {
|
||||
// need to recompute texture coordinates
|
||||
mDirty = true;
|
||||
}
|
||||
mTexture = texture;
|
||||
mPaint.setShader(new BitmapShader(texture,
|
||||
Shader.TileMode.CLAMP,
|
||||
Shader.TileMode.CLAMP));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the paint flags for the patch
|
||||
*/
|
||||
public int getPaintFlags() {
|
||||
return mPaint.getFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the paint flags for the patch
|
||||
*/
|
||||
public void setPaintFlags(int flags) {
|
||||
mPaint.setFlags(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the xfermode for the patch
|
||||
*/
|
||||
public void setXfermode(Xfermode mode) {
|
||||
mPaint.setXfermode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha for the patch
|
||||
*/
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the patch onto the canvas.
|
||||
*
|
||||
* setCubicBoundary() and setTexture() must be called before drawing.
|
||||
*/
|
||||
public void draw(Canvas canvas) {
|
||||
if (mDirty) {
|
||||
buildCache();
|
||||
mDirty = false;
|
||||
}
|
||||
|
||||
// cut the count in half, since mVerts.length is really the length of
|
||||
// the verts[] and tex[] arrays combined
|
||||
// (tex[] are stored after verts[])
|
||||
int vertCount = mVerts.length >> 1;
|
||||
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertCount,
|
||||
mVerts, 0, mVerts, vertCount, null, 0,
|
||||
mIndices, 0, mIndices.length,
|
||||
mPaint);
|
||||
}
|
||||
|
||||
private void buildCache() {
|
||||
// we need mRows * mCols points, for verts and another set for textures
|
||||
// so *2 for going from points -> floats, and *2 for verts and textures
|
||||
int vertCount = mRows * mCols * 4;
|
||||
if (mVerts == null || mVerts.length != vertCount) {
|
||||
mVerts = new float[vertCount];
|
||||
}
|
||||
|
||||
int indexCount = (mRows - 1) * (mCols - 1) * 6;
|
||||
if (mIndices == null || mIndices.length != indexCount) {
|
||||
mIndices = new short[indexCount];
|
||||
}
|
||||
|
||||
nativeComputeCubicPatch(mCubicPoints,
|
||||
mTexture.getWidth(), mTexture.getHeight(),
|
||||
mRows, mCols, mVerts, mIndices);
|
||||
}
|
||||
|
||||
private static native
|
||||
void nativeComputeCubicPatch(float[] cubicPoints,
|
||||
int texW, int texH, int rows, int cols,
|
||||
float[] verts, short[] indices);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user