• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 
17 package android.graphics.utils;
18 
19 import android.graphics.Bitmap;
20 import android.graphics.BitmapShader;
21 import android.graphics.Canvas;
22 import android.graphics.Paint;
23 import android.graphics.Shader;
24 import android.graphics.Xfermode;
25 
26 /**
27  * @hide
28  */
29 public class BoundaryPatch {
30     private Paint   mPaint;
31     private Bitmap  mTexture;
32     private int     mRows;
33     private int     mCols;
34     private float[] mCubicPoints;
35     private boolean mDirty;
36     // these are the computed output of the native code
37     private float[] mVerts;
38     private short[] mIndices;
39 
BoundaryPatch()40     public BoundaryPatch() {
41         mRows = mCols = 2;  // default minimum
42         mCubicPoints = new float[24];
43         mPaint = new Paint();
44         mPaint.setDither(true);
45         mPaint.setFilterBitmap(true);
46         mDirty = true;
47     }
48 
49     /**
50      * Set the boundary to be 4 cubics. This takes a single array of floats,
51      * and picks up the 12 pairs starting at offset, and treats them as
52      * the x,y coordinates of the cubic control points. The points wrap around
53      * a patch, as follows. For documentation purposes, pts[i] will mean the
54      * x,y pair of floats, as if pts[] were an array of "points".
55      *
56      * Top: pts[0..3]
57      * Right: pts[3..6]
58      * Bottom: pts[6..9]
59      * Right: pts[9..11], pts[0]
60      *
61      * The coordinates are copied from the input array, so subsequent changes
62      * to pts[] will not be reflected in the boundary.
63      *
64      * @param pts The src array of x,y pairs for the boundary cubics
65      * @param offset The index into pts of the first pair
66      * @param rows The number of points across to approximate the boundary.
67      *             Must be >= 2, though very large values may slow down drawing
68      * @param cols The number of points down to approximate the boundary.
69      *             Must be >= 2, though very large values may slow down drawing
70      */
setCubicBoundary(float[] pts, int offset, int rows, int cols)71     public void setCubicBoundary(float[] pts, int offset, int rows, int cols) {
72         if (rows < 2 || cols < 2) {
73             throw new RuntimeException("rows and cols must be >= 2");
74         }
75         System.arraycopy(pts, offset, mCubicPoints, 0, 24);
76         if (mRows != rows || mCols != cols) {
77             mRows = rows;
78             mCols = cols;
79         }
80         mDirty = true;
81     }
82 
83     /**
84      * Reference a bitmap texture to be mapped onto the patch.
85      */
setTexture(Bitmap texture)86     public void setTexture(Bitmap texture) {
87         if (mTexture != texture) {
88             if (mTexture == null ||
89                     mTexture.getWidth() != texture.getWidth() ||
90                     mTexture.getHeight() != texture.getHeight()) {
91                 // need to recompute texture coordinates
92                 mDirty = true;
93             }
94             mTexture = texture;
95             mPaint.setShader(new BitmapShader(texture,
96                                               Shader.TileMode.CLAMP,
97                                               Shader.TileMode.CLAMP));
98         }
99     }
100 
101     /**
102      * Return the paint flags for the patch
103      */
getPaintFlags()104     public int getPaintFlags() {
105         return mPaint.getFlags();
106     }
107 
108     /**
109      * Set the paint flags for the patch
110      */
setPaintFlags(int flags)111     public void setPaintFlags(int flags) {
112         mPaint.setFlags(flags);
113     }
114 
115     /**
116      * Set the xfermode for the patch
117      */
setXfermode(Xfermode mode)118     public void setXfermode(Xfermode mode) {
119         mPaint.setXfermode(mode);
120     }
121 
122     /**
123      * Set the alpha for the patch
124      */
setAlpha(int alpha)125     public void setAlpha(int alpha) {
126         mPaint.setAlpha(alpha);
127     }
128 
129     /**
130      * Draw the patch onto the canvas.
131      *
132      * setCubicBoundary() and setTexture() must be called before drawing.
133      */
draw(Canvas canvas)134     public void draw(Canvas canvas) {
135         if (mDirty) {
136             buildCache();
137             mDirty = false;
138         }
139 
140         // cut the count in half, since mVerts.length is really the length of
141         // the verts[] and tex[] arrays combined
142         // (tex[] are stored after verts[])
143         int vertCount = mVerts.length >> 1;
144         canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertCount,
145                             mVerts, 0, mVerts, vertCount, null, 0,
146                             mIndices, 0, mIndices.length,
147                             mPaint);
148     }
149 
buildCache()150     private void buildCache() {
151         // we need mRows * mCols points, for verts and another set for textures
152         // so *2 for going from points -> floats, and *2 for verts and textures
153         int vertCount = mRows * mCols * 4;
154         if (mVerts == null || mVerts.length != vertCount) {
155             mVerts = new float[vertCount];
156         }
157 
158         int indexCount = (mRows - 1) * (mCols - 1) * 6;
159         if (mIndices == null || mIndices.length != indexCount) {
160             mIndices = new short[indexCount];
161         }
162 
163         nativeComputeCubicPatch(mCubicPoints,
164                                 mTexture.getWidth(), mTexture.getHeight(),
165                                 mRows, mCols, mVerts, mIndices);
166     }
167 
168     private static native
nativeComputeCubicPatch(float[] cubicPoints, int texW, int texH, int rows, int cols, float[] verts, short[] indices)169     void nativeComputeCubicPatch(float[] cubicPoints,
170                                  int texW, int texH, int rows, int cols,
171                                  float[] verts, short[] indices);
172 }
173 
174