Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 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.view; |
| 18 | |
| 19 | import android.graphics.Bitmap; |
| 20 | import android.graphics.Canvas; |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 21 | import android.graphics.ColorFilter; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 22 | import android.graphics.DrawFilter; |
| 23 | import android.graphics.Matrix; |
| 24 | import android.graphics.Paint; |
| 25 | import android.graphics.Path; |
| 26 | import android.graphics.Picture; |
| 27 | import android.graphics.PorterDuff; |
| 28 | import android.graphics.Rect; |
| 29 | import android.graphics.RectF; |
| 30 | import android.graphics.Region; |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 31 | import android.graphics.Shader; |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 32 | import android.graphics.TemporaryBuffer; |
| 33 | import android.text.GraphicsOperations; |
| 34 | import android.text.SpannableString; |
| 35 | import android.text.SpannedString; |
| 36 | import android.text.TextUtils; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 37 | |
| 38 | import javax.microedition.khronos.opengles.GL; |
| 39 | |
| 40 | /** |
| 41 | * An implementation of Canvas on top of OpenGL ES 2.0. |
| 42 | */ |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 43 | class GLES20Canvas extends Canvas { |
| 44 | @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) |
| 45 | private final GL mGl; |
| 46 | private final boolean mOpaque; |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame^] | 47 | private int mRenderer; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 48 | |
| 49 | private int mWidth; |
| 50 | private int mHeight; |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 51 | |
| 52 | private final float[] mPoint = new float[2]; |
| 53 | private final float[] mLine = new float[4]; |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 54 | |
| 55 | private final Rect mClipBounds = new Rect(); |
| 56 | |
| 57 | private DrawFilter mFilter; |
Romain Guy | 1639351 | 2010-08-08 00:14:31 -0700 | [diff] [blame] | 58 | |
| 59 | /////////////////////////////////////////////////////////////////////////// |
| 60 | // JNI |
| 61 | /////////////////////////////////////////////////////////////////////////// |
| 62 | |
| 63 | private static native boolean nIsAvailable(); |
| 64 | private static boolean sIsAvailable = nIsAvailable(); |
| 65 | |
| 66 | static boolean isAvailable() { |
| 67 | return sIsAvailable; |
| 68 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 69 | |
| 70 | /////////////////////////////////////////////////////////////////////////// |
| 71 | // Constructors |
| 72 | /////////////////////////////////////////////////////////////////////////// |
| 73 | |
| 74 | GLES20Canvas(GL gl, boolean translucent) { |
| 75 | mGl = gl; |
| 76 | mOpaque = !translucent; |
| 77 | |
| 78 | mRenderer = nCreateRenderer(); |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame^] | 79 | if (mRenderer == 0) { |
| 80 | throw new IllegalStateException("Could not create GLES20Canvas renderer"); |
| 81 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 82 | } |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame^] | 83 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 84 | private native int nCreateRenderer(); |
| 85 | |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame^] | 86 | /** |
| 87 | * This method <strong>must</strong> be called before releasing a |
| 88 | * reference to a GLES20Canvas. This method is responsible for freeing |
| 89 | * native resources associated with the hardware. Not invoking this |
| 90 | * method properly can result in memory leaks. |
| 91 | * |
| 92 | * @hide |
| 93 | */ |
| 94 | public synchronized void destroy() { |
| 95 | if (mRenderer != 0) { |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 96 | nDestroyRenderer(mRenderer); |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame^] | 97 | mRenderer = 0; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 98 | } |
| 99 | } |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 100 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 101 | private native void nDestroyRenderer(int renderer); |
| 102 | |
| 103 | /////////////////////////////////////////////////////////////////////////// |
| 104 | // Canvas management |
| 105 | /////////////////////////////////////////////////////////////////////////// |
| 106 | |
| 107 | @Override |
| 108 | public boolean isHardwareAccelerated() { |
| 109 | return true; |
| 110 | } |
| 111 | |
| 112 | @Override |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 113 | public void setBitmap(Bitmap bitmap) { |
| 114 | throw new UnsupportedOperationException(); |
| 115 | } |
| 116 | |
| 117 | @Override |
| 118 | public boolean isOpaque() { |
| 119 | return mOpaque; |
| 120 | } |
| 121 | |
| 122 | @Override |
| 123 | public int getWidth() { |
| 124 | return mWidth; |
| 125 | } |
| 126 | |
| 127 | @Override |
| 128 | public int getHeight() { |
| 129 | return mHeight; |
| 130 | } |
| 131 | |
| 132 | /////////////////////////////////////////////////////////////////////////// |
| 133 | // Setup |
| 134 | /////////////////////////////////////////////////////////////////////////// |
| 135 | |
| 136 | @Override |
| 137 | public void setViewport(int width, int height) { |
| 138 | mWidth = width; |
| 139 | mHeight = height; |
| 140 | |
| 141 | nSetViewport(mRenderer, width, height); |
| 142 | } |
| 143 | |
| 144 | private native void nSetViewport(int renderer, int width, int height); |
| 145 | |
| 146 | void onPreDraw() { |
| 147 | nPrepare(mRenderer); |
| 148 | } |
| 149 | |
| 150 | private native void nPrepare(int renderer); |
| 151 | |
| 152 | /////////////////////////////////////////////////////////////////////////// |
| 153 | // Clipping |
| 154 | /////////////////////////////////////////////////////////////////////////// |
| 155 | |
| 156 | @Override |
| 157 | public boolean clipPath(Path path) { |
| 158 | throw new UnsupportedOperationException(); |
| 159 | } |
| 160 | |
| 161 | @Override |
| 162 | public boolean clipPath(Path path, Region.Op op) { |
| 163 | throw new UnsupportedOperationException(); |
| 164 | } |
| 165 | |
| 166 | @Override |
| 167 | public boolean clipRect(float left, float top, float right, float bottom) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 168 | return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 169 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 170 | |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 171 | private native boolean nClipRect(int renderer, float left, float top, |
| 172 | float right, float bottom, int op); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 173 | |
| 174 | @Override |
| 175 | public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 176 | return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | @Override |
| 180 | public boolean clipRect(int left, int top, int right, int bottom) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 181 | return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 182 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 183 | |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 184 | private native boolean nClipRect(int renderer, int left, int top, int right, int bottom, int op); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 185 | |
| 186 | @Override |
| 187 | public boolean clipRect(Rect rect) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 188 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, |
| 189 | Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | @Override |
| 193 | public boolean clipRect(Rect rect, Region.Op op) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 194 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 195 | } |
| 196 | |
| 197 | @Override |
| 198 | public boolean clipRect(RectF rect) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 199 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, |
| 200 | Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 201 | } |
| 202 | |
| 203 | @Override |
| 204 | public boolean clipRect(RectF rect, Region.Op op) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 205 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 206 | } |
| 207 | |
| 208 | @Override |
| 209 | public boolean clipRegion(Region region) { |
| 210 | throw new UnsupportedOperationException(); |
| 211 | } |
| 212 | |
| 213 | @Override |
| 214 | public boolean clipRegion(Region region, Region.Op op) { |
| 215 | throw new UnsupportedOperationException(); |
| 216 | } |
| 217 | |
| 218 | @Override |
| 219 | public boolean getClipBounds(Rect bounds) { |
Romain Guy | 9d5316e | 2010-06-24 19:30:36 -0700 | [diff] [blame] | 220 | return nGetClipBounds(mRenderer, bounds); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 221 | } |
| 222 | |
Romain Guy | 9d5316e | 2010-06-24 19:30:36 -0700 | [diff] [blame] | 223 | private native boolean nGetClipBounds(int renderer, Rect bounds); |
| 224 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 225 | @Override |
| 226 | public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 227 | return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 228 | } |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 229 | |
| 230 | private native boolean nQuickReject(int renderer, float left, float top, |
| 231 | float right, float bottom, int edge); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 232 | |
| 233 | @Override |
| 234 | public boolean quickReject(Path path, EdgeType type) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 235 | throw new UnsupportedOperationException(); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | @Override |
| 239 | public boolean quickReject(RectF rect, EdgeType type) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 240 | return quickReject(rect.left, rect.top, rect.right, rect.bottom, type); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 241 | } |
| 242 | |
| 243 | /////////////////////////////////////////////////////////////////////////// |
| 244 | // Transformations |
| 245 | /////////////////////////////////////////////////////////////////////////// |
| 246 | |
| 247 | @Override |
| 248 | public void translate(float dx, float dy) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 249 | nTranslate(mRenderer, dx, dy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 250 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 251 | |
| 252 | private native void nTranslate(int renderer, float dx, float dy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 253 | |
| 254 | @Override |
| 255 | public void skew(float sx, float sy) { |
| 256 | throw new UnsupportedOperationException(); |
| 257 | } |
| 258 | |
| 259 | @Override |
| 260 | public void rotate(float degrees) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 261 | nRotate(mRenderer, degrees); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 262 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 263 | |
| 264 | private native void nRotate(int renderer, float degrees); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 265 | |
| 266 | @Override |
| 267 | public void scale(float sx, float sy) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 268 | nScale(mRenderer, sx, sy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 269 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 270 | |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 271 | private native void nScale(int renderer, float sx, float sy); |
| 272 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 273 | @Override |
| 274 | public void setMatrix(Matrix matrix) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 275 | nSetMatrix(mRenderer, matrix.native_instance); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 276 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 277 | |
| 278 | private native void nSetMatrix(int renderer, int matrix); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 279 | |
| 280 | @Override |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 281 | public void getMatrix(Matrix matrix) { |
| 282 | nGetMatrix(mRenderer, matrix.native_instance); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 283 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 284 | |
| 285 | private native void nGetMatrix(int renderer, int matrix); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 286 | |
| 287 | @Override |
| 288 | public void concat(Matrix matrix) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 289 | nConcatMatrix(mRenderer, matrix.native_instance); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 290 | } |
| 291 | |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 292 | private native void nConcatMatrix(int renderer, int matrix); |
| 293 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 294 | /////////////////////////////////////////////////////////////////////////// |
| 295 | // State management |
| 296 | /////////////////////////////////////////////////////////////////////////// |
| 297 | |
| 298 | @Override |
| 299 | public int save() { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 300 | return nSave(mRenderer, 0); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 301 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 302 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 303 | @Override |
| 304 | public int save(int saveFlags) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 305 | return nSave(mRenderer, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 306 | } |
| 307 | |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 308 | private native int nSave(int renderer, int flags); |
| 309 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 310 | @Override |
| 311 | public int saveLayer(RectF bounds, Paint paint, int saveFlags) { |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 312 | return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 313 | } |
| 314 | |
| 315 | @Override |
| 316 | public int saveLayer(float left, float top, float right, float bottom, Paint paint, |
| 317 | int saveFlags) { |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 318 | int nativePaint = paint == null ? 0 : paint.mNativePaint; |
| 319 | return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 320 | } |
| 321 | |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 322 | private native int nSaveLayer(int renderer, float left, float top, float right, float bottom, |
| 323 | int paint, int saveFlags); |
| 324 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 325 | @Override |
| 326 | public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 327 | return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, |
| 328 | alpha, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 329 | } |
| 330 | |
| 331 | @Override |
| 332 | public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, |
| 333 | int saveFlags) { |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 334 | return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 335 | } |
| 336 | |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 337 | private native int nSaveLayerAlpha(int renderer, float left, float top, float right, |
| 338 | float bottom, int alpha, int saveFlags); |
| 339 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 340 | @Override |
| 341 | public void restore() { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 342 | nRestore(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 343 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 344 | |
| 345 | private native void nRestore(int renderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 346 | |
| 347 | @Override |
| 348 | public void restoreToCount(int saveCount) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 349 | nRestoreToCount(mRenderer, saveCount); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 350 | } |
| 351 | |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 352 | private native void nRestoreToCount(int renderer, int saveCount); |
| 353 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 354 | @Override |
| 355 | public int getSaveCount() { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 356 | return nGetSaveCount(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 357 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 358 | |
| 359 | private native int nGetSaveCount(int renderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 360 | |
| 361 | /////////////////////////////////////////////////////////////////////////// |
| 362 | // Filtering |
| 363 | /////////////////////////////////////////////////////////////////////////// |
| 364 | |
| 365 | @Override |
| 366 | public void setDrawFilter(DrawFilter filter) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 367 | mFilter = filter; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 368 | } |
| 369 | |
| 370 | @Override |
| 371 | public DrawFilter getDrawFilter() { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 372 | return mFilter; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 373 | } |
| 374 | |
| 375 | /////////////////////////////////////////////////////////////////////////// |
| 376 | // Drawing |
| 377 | /////////////////////////////////////////////////////////////////////////// |
| 378 | |
| 379 | @Override |
| 380 | public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, |
| 381 | Paint paint) { |
| 382 | throw new UnsupportedOperationException(); |
| 383 | } |
| 384 | |
| 385 | @Override |
| 386 | public void drawARGB(int a, int r, int g, int b) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 387 | drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 388 | } |
| 389 | |
| 390 | @Override |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 391 | public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 392 | // Shaders are ignored when drawing patches |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 393 | boolean hasColorFilter = paint != null && setupColorFilter(paint); |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 394 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 395 | nDrawPatch(mRenderer, bitmap.mNativeBitmap, chunks, dst.left, dst.top, |
| 396 | dst.right, dst.bottom, nativePaint); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 397 | if (hasColorFilter) nResetModifiers(mRenderer); |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 398 | } |
| 399 | |
| 400 | private native void nDrawPatch(int renderer, int bitmap, byte[] chunks, float left, float top, |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 401 | float right, float bottom, int paint); |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 402 | |
| 403 | @Override |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 404 | public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 405 | // Shaders are ignored when drawing bitmaps |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 406 | boolean hasColorFilter = paint != null && setupColorFilter(paint); |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 407 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 408 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 409 | if (hasColorFilter) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 410 | } |
| 411 | |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 412 | private native void nDrawBitmap(int renderer, int bitmap, float left, float top, int paint); |
| 413 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 414 | @Override |
| 415 | public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 416 | // Shaders are ignored when drawing bitmaps |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 417 | boolean hasColorFilter = paint != null && setupColorFilter(paint); |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 418 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 419 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 420 | if (hasColorFilter) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 421 | } |
| 422 | |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 423 | private native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint); |
Romain Guy | f86ef57 | 2010-07-01 11:05:42 -0700 | [diff] [blame] | 424 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 425 | @Override |
| 426 | public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 427 | // Shaders are ignored when drawing bitmaps |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 428 | boolean hasColorFilter = paint != null && setupColorFilter(paint); |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 429 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Romain Guy | 694b519 | 2010-07-21 21:33:20 -0700 | [diff] [blame] | 430 | |
| 431 | int left, top, right, bottom; |
| 432 | if (src == null) { |
| 433 | left = top = 0; |
| 434 | right = bitmap.getWidth(); |
| 435 | bottom = bitmap.getHeight(); |
| 436 | } else { |
| 437 | left = src.left; |
| 438 | right = src.right; |
| 439 | top = src.top; |
| 440 | bottom = src.bottom; |
| 441 | } |
| 442 | |
| 443 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom, |
| 444 | dst.left, dst.top, dst.right, dst.bottom, nativePaint); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 445 | if (hasColorFilter) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 446 | } |
| 447 | |
| 448 | @Override |
| 449 | public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 450 | // Shaders are ignored when drawing bitmaps |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 451 | boolean hasColorFilter = paint != null && setupColorFilter(paint); |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 452 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
| 453 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, src.left, src.top, src.right, src.bottom, |
Romain Guy | 694b519 | 2010-07-21 21:33:20 -0700 | [diff] [blame] | 454 | dst.left, dst.top, dst.right, dst.bottom, nativePaint); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 455 | if (hasColorFilter) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 456 | } |
| 457 | |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 458 | private native void nDrawBitmap(int renderer, int bitmap, |
| 459 | float srcLeft, float srcTop, float srcRight, float srcBottom, |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 460 | float left, float top, float right, float bottom, int paint); |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 461 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 462 | @Override |
| 463 | public void drawBitmap(int[] colors, int offset, int stride, float x, float y, |
| 464 | int width, int height, boolean hasAlpha, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 465 | // Shaders are ignored when drawing bitmaps |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 466 | boolean hasColorFilter = paint != null && setupColorFilter(paint); |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 467 | final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; |
| 468 | final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config); |
| 469 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
| 470 | nDrawBitmap(mRenderer, b.mNativeBitmap, x, y, nativePaint); |
| 471 | b.recycle(); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 472 | if (hasColorFilter) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 473 | } |
| 474 | |
| 475 | @Override |
| 476 | public void drawBitmap(int[] colors, int offset, int stride, int x, int y, |
| 477 | int width, int height, boolean hasAlpha, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 478 | // Shaders are ignored when drawing bitmaps |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 479 | drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 480 | } |
| 481 | |
| 482 | @Override |
| 483 | public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, |
| 484 | int vertOffset, int[] colors, int colorOffset, Paint paint) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 485 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 486 | } |
| 487 | |
| 488 | @Override |
| 489 | public void drawCircle(float cx, float cy, float radius, Paint paint) { |
| 490 | throw new UnsupportedOperationException(); |
| 491 | } |
| 492 | |
| 493 | @Override |
| 494 | public void drawColor(int color) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 495 | drawColor(color, PorterDuff.Mode.SRC_OVER); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 496 | } |
| 497 | |
| 498 | @Override |
| 499 | public void drawColor(int color, PorterDuff.Mode mode) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 500 | nDrawColor(mRenderer, color, mode.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 501 | } |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 502 | |
| 503 | private native void nDrawColor(int renderer, int color, int mode); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 504 | |
| 505 | @Override |
| 506 | public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 507 | mLine[0] = startX; |
| 508 | mLine[1] = startY; |
| 509 | mLine[2] = stopX; |
| 510 | mLine[3] = stopY; |
| 511 | drawLines(mLine, 0, 1, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 512 | } |
| 513 | |
| 514 | @Override |
| 515 | public void drawLines(float[] pts, int offset, int count, Paint paint) { |
| 516 | // TODO: Implement |
| 517 | } |
| 518 | |
| 519 | @Override |
| 520 | public void drawLines(float[] pts, Paint paint) { |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 521 | drawLines(pts, 0, pts.length / 4, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 522 | } |
| 523 | |
| 524 | @Override |
| 525 | public void drawOval(RectF oval, Paint paint) { |
| 526 | throw new UnsupportedOperationException(); |
| 527 | } |
| 528 | |
| 529 | @Override |
| 530 | public void drawPaint(Paint paint) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 531 | final Rect r = mClipBounds; |
| 532 | nGetClipBounds(mRenderer, r); |
| 533 | drawRect(r.left, r.top, r.right, r.bottom, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 534 | } |
| 535 | |
| 536 | @Override |
| 537 | public void drawPath(Path path, Paint paint) { |
Romain Guy | 7fbcc04 | 2010-08-04 15:40:07 -0700 | [diff] [blame] | 538 | boolean hasModifier = setupModifiers(paint); |
Romain Guy | a48a1a8 | 2010-08-10 14:59:15 -0700 | [diff] [blame] | 539 | if (path.isSimplePath) { |
| 540 | if (path.rects != null) { |
| 541 | nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint); |
| 542 | } |
| 543 | } else { |
| 544 | nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint); |
| 545 | } |
Romain Guy | 7fbcc04 | 2010-08-04 15:40:07 -0700 | [diff] [blame] | 546 | if (hasModifier) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 547 | } |
| 548 | |
Romain Guy | 7fbcc04 | 2010-08-04 15:40:07 -0700 | [diff] [blame] | 549 | private native void nDrawPath(int renderer, int path, int paint); |
Romain Guy | a48a1a8 | 2010-08-10 14:59:15 -0700 | [diff] [blame] | 550 | private native void nDrawRects(int renderer, int region, int paint); |
Romain Guy | 7fbcc04 | 2010-08-04 15:40:07 -0700 | [diff] [blame] | 551 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 552 | @Override |
| 553 | public void drawPicture(Picture picture) { |
| 554 | throw new UnsupportedOperationException(); |
| 555 | } |
| 556 | |
| 557 | @Override |
| 558 | public void drawPicture(Picture picture, Rect dst) { |
| 559 | throw new UnsupportedOperationException(); |
| 560 | } |
| 561 | |
| 562 | @Override |
| 563 | public void drawPicture(Picture picture, RectF dst) { |
| 564 | throw new UnsupportedOperationException(); |
| 565 | } |
| 566 | |
| 567 | @Override |
| 568 | public void drawPoint(float x, float y, Paint paint) { |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 569 | mPoint[0] = x; |
| 570 | mPoint[1] = y; |
| 571 | drawPoints(mPoint, 0, 1, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 572 | } |
| 573 | |
| 574 | @Override |
| 575 | public void drawPoints(float[] pts, int offset, int count, Paint paint) { |
| 576 | // TODO: Implement |
| 577 | } |
| 578 | |
| 579 | @Override |
| 580 | public void drawPoints(float[] pts, Paint paint) { |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 581 | drawPoints(pts, 0, pts.length / 2, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 582 | } |
| 583 | |
| 584 | @Override |
| 585 | public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { |
| 586 | throw new UnsupportedOperationException(); |
| 587 | } |
| 588 | |
| 589 | @Override |
| 590 | public void drawPosText(String text, float[] pos, Paint paint) { |
| 591 | throw new UnsupportedOperationException(); |
| 592 | } |
| 593 | |
| 594 | @Override |
| 595 | public void drawRect(float left, float top, float right, float bottom, Paint paint) { |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 596 | boolean hasModifier = setupModifiers(paint); |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 597 | nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 598 | if (hasModifier) nResetModifiers(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 599 | } |
| 600 | |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 601 | private native void nDrawRect(int renderer, float left, float top, float right, float bottom, |
| 602 | int paint); |
| 603 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 604 | @Override |
| 605 | public void drawRect(Rect r, Paint paint) { |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 606 | drawRect(r.left, r.top, r.right, r.bottom, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 607 | } |
| 608 | |
| 609 | @Override |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 610 | public void drawRect(RectF r, Paint paint) { |
| 611 | drawRect(r.left, r.top, r.right, r.bottom, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 612 | } |
| 613 | |
| 614 | @Override |
| 615 | public void drawRGB(int r, int g, int b) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 616 | drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 617 | } |
| 618 | |
| 619 | @Override |
| 620 | public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 621 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 622 | } |
| 623 | |
| 624 | @Override |
| 625 | public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 626 | if ((index | count | (index + count) | (text.length - index - count)) < 0) { |
| 627 | throw new IndexOutOfBoundsException(); |
| 628 | } |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 629 | |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 630 | boolean hasModifier = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 631 | try { |
| 632 | nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint); |
| 633 | } finally { |
| 634 | if (hasModifier) nResetModifiers(mRenderer); |
| 635 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 636 | } |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 637 | |
| 638 | private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y, |
| 639 | int bidiFlags, int paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 640 | |
| 641 | @Override |
| 642 | public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 643 | boolean hasModifier = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 644 | try { |
| 645 | if (text instanceof String || text instanceof SpannedString || |
| 646 | text instanceof SpannableString) { |
| 647 | nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, |
| 648 | paint.mNativePaint); |
| 649 | } else if (text instanceof GraphicsOperations) { |
| 650 | ((GraphicsOperations) text).drawText(this, start, end, x, y, |
| 651 | paint); |
| 652 | } else { |
| 653 | char[] buf = TemporaryBuffer.obtain(end - start); |
| 654 | TextUtils.getChars(text, start, end, buf, 0); |
| 655 | nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint); |
| 656 | TemporaryBuffer.recycle(buf); |
| 657 | } |
| 658 | } finally { |
| 659 | if (hasModifier) nResetModifiers(mRenderer); |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 660 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 661 | } |
| 662 | |
| 663 | @Override |
| 664 | public void drawText(String text, int start, int end, float x, float y, Paint paint) { |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 665 | if ((start | end | (end - start) | (text.length() - end)) < 0) { |
| 666 | throw new IndexOutOfBoundsException(); |
| 667 | } |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 668 | |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 669 | boolean hasModifier = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 670 | try { |
| 671 | nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint); |
| 672 | } finally { |
| 673 | if (hasModifier) nResetModifiers(mRenderer); |
| 674 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 675 | } |
| 676 | |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 677 | private native void nDrawText(int renderer, String text, int start, int end, float x, float y, |
| 678 | int bidiFlags, int paint); |
| 679 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 680 | @Override |
| 681 | public void drawText(String text, float x, float y, Paint paint) { |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 682 | boolean hasModifier = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 683 | try { |
| 684 | nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, |
| 685 | paint.mNativePaint); |
| 686 | } finally { |
| 687 | if (hasModifier) nResetModifiers(mRenderer); |
| 688 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 689 | } |
| 690 | |
| 691 | @Override |
| 692 | public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, |
| 693 | float vOffset, Paint paint) { |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 694 | throw new UnsupportedOperationException(); |
| 695 | } |
| 696 | |
| 697 | @Override |
| 698 | public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { |
| 699 | throw new UnsupportedOperationException(); |
| 700 | } |
| 701 | |
| 702 | @Override |
| 703 | public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, |
| 704 | float x, float y, int dir, Paint paint) { |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 705 | if ((index | count | text.length - index - count) < 0) { |
| 706 | throw new IndexOutOfBoundsException(); |
| 707 | } |
| 708 | if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { |
| 709 | throw new IllegalArgumentException("Unknown direction: " + dir); |
| 710 | } |
| 711 | |
| 712 | boolean hasModifier = setupModifiers(paint); |
| 713 | try { |
| 714 | nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, |
| 715 | paint.mNativePaint); |
| 716 | } finally { |
| 717 | if (hasModifier) nResetModifiers(mRenderer); |
| 718 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 719 | } |
| 720 | |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 721 | private native void nDrawTextRun(int renderer, char[] text, int index, int count, |
| 722 | int contextIndex, int contextCount, float x, float y, int dir, int nativePaint); |
| 723 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 724 | @Override |
| 725 | public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, |
| 726 | float x, float y, int dir, Paint paint) { |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 727 | if ((start | end | end - start | text.length() - end) < 0) { |
| 728 | throw new IndexOutOfBoundsException(); |
| 729 | } |
| 730 | |
| 731 | boolean hasModifier = setupModifiers(paint); |
| 732 | try { |
| 733 | int flags = dir == 0 ? 0 : 1; |
| 734 | if (text instanceof String || text instanceof SpannedString || |
| 735 | text instanceof SpannableString) { |
| 736 | nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, |
| 737 | contextEnd, x, y, flags, paint.mNativePaint); |
| 738 | } else if (text instanceof GraphicsOperations) { |
| 739 | ((GraphicsOperations) text).drawTextRun(this, start, end, |
| 740 | contextStart, contextEnd, x, y, flags, paint); |
| 741 | } else { |
| 742 | int contextLen = contextEnd - contextStart; |
| 743 | int len = end - start; |
| 744 | char[] buf = TemporaryBuffer.obtain(contextLen); |
| 745 | TextUtils.getChars(text, contextStart, contextEnd, buf, 0); |
| 746 | nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, |
| 747 | x, y, flags, paint.mNativePaint); |
| 748 | TemporaryBuffer.recycle(buf); |
| 749 | } |
| 750 | } finally { |
| 751 | if (hasModifier) nResetModifiers(mRenderer); |
| 752 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 753 | } |
| 754 | |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 755 | private native void nDrawTextRun(int renderer, String text, int start, int end, |
| 756 | int contextStart, int contextEnd, float x, float y, int flags, int nativePaint); |
| 757 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 758 | @Override |
| 759 | public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, |
| 760 | float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, |
| 761 | int indexOffset, int indexCount, Paint paint) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 762 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 763 | } |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 764 | |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 765 | private boolean setupModifiers(Paint paint) { |
| 766 | boolean hasModifier = false; |
| 767 | |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 768 | if (paint.hasShadow) { |
| 769 | nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy, |
| 770 | paint.shadowColor); |
| 771 | hasModifier = true; |
| 772 | } |
| 773 | |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 774 | final Shader shader = paint.getShader(); |
| 775 | if (shader != null) { |
Romain Guy | 06f96e2 | 2010-07-30 19:18:16 -0700 | [diff] [blame] | 776 | nSetupShader(mRenderer, shader.native_shader); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 777 | hasModifier = true; |
| 778 | } |
| 779 | |
| 780 | final ColorFilter filter = paint.getColorFilter(); |
| 781 | if (filter != null) { |
| 782 | nSetupColorFilter(mRenderer, filter.nativeColorFilter); |
| 783 | hasModifier = true; |
| 784 | } |
| 785 | |
| 786 | return hasModifier; |
| 787 | } |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 788 | |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 789 | private boolean setupColorFilter(Paint paint) { |
| 790 | final ColorFilter filter = paint.getColorFilter(); |
| 791 | if (filter != null) { |
| 792 | nSetupColorFilter(mRenderer, filter.nativeColorFilter); |
Romain Guy | 06f96e2 | 2010-07-30 19:18:16 -0700 | [diff] [blame] | 793 | return true; |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 794 | } |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 795 | return false; |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 796 | } |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 797 | |
Romain Guy | 06f96e2 | 2010-07-30 19:18:16 -0700 | [diff] [blame] | 798 | private native void nSetupShader(int renderer, int shader); |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 799 | private native void nSetupColorFilter(int renderer, int colorFilter); |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 800 | private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color); |
| 801 | |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 802 | private native void nResetModifiers(int renderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 803 | } |