blob: dc68e51bfc11487b1a3d104df9ce5a48d223ebc5 [file] [log] [blame]
Romain Guye4d01122010-06-16 18:44:05 -07001/*
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
17package android.view;
18
19import android.graphics.Bitmap;
20import android.graphics.Canvas;
Romain Guydb1938e2010-08-02 18:50:22 -070021import android.graphics.ColorFilter;
Romain Guye4d01122010-06-16 18:44:05 -070022import android.graphics.DrawFilter;
23import android.graphics.Matrix;
Romain Guy3b748a42013-04-17 18:54:38 -070024import android.graphics.NinePatch;
Romain Guye4d01122010-06-16 18:44:05 -070025import android.graphics.Paint;
Romain Guy5ff9df62012-01-23 17:09:05 -080026import android.graphics.PaintFlagsDrawFilter;
Romain Guye4d01122010-06-16 18:44:05 -070027import android.graphics.Path;
28import android.graphics.Picture;
29import android.graphics.PorterDuff;
30import android.graphics.Rect;
31import android.graphics.RectF;
32import android.graphics.Region;
Romain Guyd27977d2010-07-14 19:18:51 -070033import android.graphics.Shader;
Romain Guye5e0c502011-06-15 15:18:31 -070034import android.graphics.SurfaceTexture;
Romain Guya1db5742010-07-20 13:09:13 -070035import android.graphics.TemporaryBuffer;
36import android.text.GraphicsOperations;
37import android.text.SpannableString;
38import android.text.SpannedString;
39import android.text.TextUtils;
Romain Guye4d01122010-06-16 18:44:05 -070040
Romain Guye4d01122010-06-16 18:44:05 -070041/**
42 * An implementation of Canvas on top of OpenGL ES 2.0.
43 */
Romain Guyb051e892010-09-28 19:09:36 -070044class GLES20Canvas extends HardwareCanvas {
Romain Guya168d732011-03-18 16:50:13 -070045 // Must match modifiers used in the JNI layer
46 private static final int MODIFIER_NONE = 0;
47 private static final int MODIFIER_SHADOW = 1;
48 private static final int MODIFIER_SHADER = 2;
49 private static final int MODIFIER_COLOR_FILTER = 4;
50
Romain Guye4d01122010-06-16 18:44:05 -070051 private final boolean mOpaque;
Ashok Bhat36bef0b2014-01-20 20:08:01 +000052 private long mRenderer;
Patrick Dubroyf890fab2010-12-19 16:47:17 -080053
54 // The native renderer will be destroyed when this object dies.
55 // DO NOT overwrite this reference once it is set.
Romain Guyeea60692011-07-26 20:35:55 -070056 @SuppressWarnings({"unused", "FieldCanBeLocal"})
Patrick Dubroyf890fab2010-12-19 16:47:17 -080057 private CanvasFinalizer mFinalizer;
58
Romain Guye4d01122010-06-16 18:44:05 -070059 private int mWidth;
60 private int mHeight;
Romain Guyce0537b2010-06-29 21:05:21 -070061
Romain Guy6410c0a2013-06-17 11:21:58 -070062 private float[] mPoint;
63 private float[] mLine;
Romain Guy6926c722010-07-12 20:20:03 -070064
Romain Guy6410c0a2013-06-17 11:21:58 -070065 private Rect mClipBounds;
66 private RectF mPathBounds;
Romain Guy6926c722010-07-12 20:20:03 -070067
68 private DrawFilter mFilter;
Romain Guyda8532c2010-08-31 11:50:35 -070069
Romain Guy16393512010-08-08 00:14:31 -070070 ///////////////////////////////////////////////////////////////////////////
71 // JNI
72 ///////////////////////////////////////////////////////////////////////////
73
74 private static native boolean nIsAvailable();
75 private static boolean sIsAvailable = nIsAvailable();
76
77 static boolean isAvailable() {
78 return sIsAvailable;
79 }
Romain Guye4d01122010-06-16 18:44:05 -070080
81 ///////////////////////////////////////////////////////////////////////////
82 // Constructors
83 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070084
Romain Guy6c319ca2011-01-11 14:29:25 -080085 /**
86 * Creates a canvas to render directly on screen.
87 */
Romain Guyb051e892010-09-28 19:09:36 -070088 GLES20Canvas(boolean translucent) {
89 this(false, translucent);
90 }
Romain Guy6c319ca2011-01-11 14:29:25 -080091
92 /**
93 * Creates a canvas to render into an FBO.
94 */
Ashok Bhat36bef0b2014-01-20 20:08:01 +000095 GLES20Canvas(long layer, boolean translucent) {
Romain Guy6c319ca2011-01-11 14:29:25 -080096 mOpaque = !translucent;
Romain Guyada830f2011-01-13 12:13:20 -080097 mRenderer = nCreateLayerRenderer(layer);
Romain Guy6c319ca2011-01-11 14:29:25 -080098 setupFinalizer();
99 }
Romain Guye4d01122010-06-16 18:44:05 -0700100
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800101 protected GLES20Canvas(boolean record, boolean translucent) {
Romain Guye4d01122010-06-16 18:44:05 -0700102 mOpaque = !translucent;
103
Romain Guyb051e892010-09-28 19:09:36 -0700104 if (record) {
Jeff Brown162a0212011-07-21 17:02:54 -0700105 mRenderer = nCreateDisplayListRenderer();
Romain Guyb051e892010-09-28 19:09:36 -0700106 } else {
107 mRenderer = nCreateRenderer();
108 }
Romain Guy6c319ca2011-01-11 14:29:25 -0800109
110 setupFinalizer();
111 }
112
113 private void setupFinalizer() {
Romain Guyfb8b7632010-08-23 21:05:08 -0700114 if (mRenderer == 0) {
115 throw new IllegalStateException("Could not create GLES20Canvas renderer");
Chet Haase5c13d892010-10-08 08:37:55 -0700116 } else {
Jeff Brown162a0212011-07-21 17:02:54 -0700117 mFinalizer = new CanvasFinalizer(mRenderer);
Romain Guyfb8b7632010-08-23 21:05:08 -0700118 }
Romain Guye4d01122010-06-16 18:44:05 -0700119 }
Romain Guye4d01122010-06-16 18:44:05 -0700120
Jeff Brown162a0212011-07-21 17:02:54 -0700121 protected void resetDisplayListRenderer() {
122 nResetDisplayListRenderer(mRenderer);
123 }
124
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000125 private static native long nCreateRenderer();
126 private static native long nCreateLayerRenderer(long layer);
127 private static native long nCreateDisplayListRenderer();
128 private static native void nResetDisplayListRenderer(long renderer);
129 private static native void nDestroyRenderer(long renderer);
Chet Haase5c13d892010-10-08 08:37:55 -0700130
Jeff Brown162a0212011-07-21 17:02:54 -0700131 private static final class CanvasFinalizer {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000132 private final long mRenderer;
Chet Haase5c13d892010-10-08 08:37:55 -0700133
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000134 public CanvasFinalizer(long renderer) {
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800135 mRenderer = renderer;
Chet Haase5c13d892010-10-08 08:37:55 -0700136 }
137
138 @Override
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800139 protected void finalize() throws Throwable {
Romain Guy171c5922011-01-06 10:04:23 -0800140 try {
Jeff Brown162a0212011-07-21 17:02:54 -0700141 nDestroyRenderer(mRenderer);
Romain Guy171c5922011-01-06 10:04:23 -0800142 } finally {
143 super.finalize();
144 }
Romain Guye4d01122010-06-16 18:44:05 -0700145 }
146 }
Romain Guyce0537b2010-06-29 21:05:21 -0700147
Chris Craikba9b6132013-12-15 17:10:19 -0800148 public static void setProperty(String name, String value) {
149 nSetProperty(name, value);
150 }
151
152 private static native void nSetProperty(String name, String value);
153
Romain Guye4d01122010-06-16 18:44:05 -0700154 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800155 // Hardware layers
156 ///////////////////////////////////////////////////////////////////////////
Romain Guy11cb6422012-09-21 00:39:43 -0700157
158 @Override
159 void pushLayerUpdate(HardwareLayer layer) {
160 nPushLayerUpdate(mRenderer, ((GLES20RenderLayer) layer).mLayer);
161 }
162
163 @Override
Romain Guye93482f2013-06-17 13:14:51 -0700164 void cancelLayerUpdate(HardwareLayer layer) {
165 nCancelLayerUpdate(mRenderer, ((GLES20RenderLayer) layer).mLayer);
166 }
167
168 @Override
Romain Guy40543602013-06-12 15:31:28 -0700169 void flushLayerUpdates() {
170 nFlushLayerUpdates(mRenderer);
171 }
172
173 @Override
Romain Guy11cb6422012-09-21 00:39:43 -0700174 void clearLayerUpdates() {
175 nClearLayerUpdates(mRenderer);
176 }
177
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000178 static native long nCreateTextureLayer(boolean opaque, int[] layerInfo);
179 static native long nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
180 static native boolean nResizeLayer(long layerId, int width, int height, int[] layerInfo);
181 static native void nSetOpaqueLayer(long layerId, boolean isOpaque);
182 static native void nSetLayerPaint(long layerId, long nativePaint);
183 static native void nSetLayerColorFilter(long layerId, long nativeColorFilter);
184 static native void nUpdateTextureLayer(long layerId, int width, int height, boolean opaque,
Romain Guya9489272011-06-22 20:58:11 -0700185 SurfaceTexture surface);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000186 static native void nClearLayerTexture(long layerId);
187 static native void nSetTextureLayerTransform(long layerId, long matrix);
188 static native void nDestroyLayer(long layerId);
189 static native void nDestroyLayerDeferred(long layerId);
190 static native void nUpdateRenderLayer(long layerId, long renderer, long displayList,
Romain Guy2bf68f02012-03-02 13:37:47 -0800191 int left, int top, int right, int bottom);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000192 static native boolean nCopyLayer(long layerId, long bitmap);
Romain Guy57066eb2011-01-12 12:53:32 -0800193
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000194 private static native void nClearLayerUpdates(long renderer);
195 private static native void nFlushLayerUpdates(long renderer);
196 private static native void nPushLayerUpdate(long renderer, long layer);
197 private static native void nCancelLayerUpdate(long renderer, long layer);
Romain Guy11cb6422012-09-21 00:39:43 -0700198
Romain Guy6c319ca2011-01-11 14:29:25 -0800199 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700200 // Canvas management
201 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700202
203 @Override
204 public boolean isOpaque() {
205 return mOpaque;
206 }
207
208 @Override
209 public int getWidth() {
210 return mWidth;
211 }
212
213 @Override
214 public int getHeight() {
215 return mHeight;
216 }
217
Romain Guyf61970fc2011-07-07 14:10:06 -0700218 @Override
219 public int getMaximumBitmapWidth() {
220 return nGetMaximumTextureWidth();
221 }
222
223 @Override
224 public int getMaximumBitmapHeight() {
225 return nGetMaximumTextureHeight();
226 }
227
228 private static native int nGetMaximumTextureWidth();
Romain Guy530041d2012-01-25 18:56:29 -0800229 private static native int nGetMaximumTextureHeight();
Romain Guyf61970fc2011-07-07 14:10:06 -0700230
Romain Guy2bf68f02012-03-02 13:37:47 -0800231 /**
232 * Returns the native OpenGLRenderer object.
233 */
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000234 long getRenderer() {
Romain Guy2bf68f02012-03-02 13:37:47 -0800235 return mRenderer;
236 }
237
Romain Guye4d01122010-06-16 18:44:05 -0700238 ///////////////////////////////////////////////////////////////////////////
239 // Setup
240 ///////////////////////////////////////////////////////////////////////////
241
242 @Override
243 public void setViewport(int width, int height) {
244 mWidth = width;
245 mHeight = height;
246
247 nSetViewport(mRenderer, width, height);
248 }
249
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000250 private static native void nSetViewport(long renderer, int width, int height);
Romain Guye4d01122010-06-16 18:44:05 -0700251
Romain Guy7d7b5492011-01-24 16:33:45 -0800252 @Override
Chet Haase44b2fe32012-06-06 19:03:58 -0700253 public int onPreDraw(Rect dirty) {
Romain Guy7d7b5492011-01-24 16:33:45 -0800254 if (dirty != null) {
Chet Haase44b2fe32012-06-06 19:03:58 -0700255 return nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom,
256 mOpaque);
Romain Guy7d7b5492011-01-24 16:33:45 -0800257 } else {
Chet Haase44b2fe32012-06-06 19:03:58 -0700258 return nPrepare(mRenderer, mOpaque);
Romain Guy7d7b5492011-01-24 16:33:45 -0800259 }
260 }
261
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000262 private static native int nPrepare(long renderer, boolean opaque);
263 private static native int nPrepareDirty(long renderer, int left, int top, int right, int bottom,
Romain Guy7d7b5492011-01-24 16:33:45 -0800264 boolean opaque);
Romain Guye4d01122010-06-16 18:44:05 -0700265
Romain Guyb051e892010-09-28 19:09:36 -0700266 @Override
Gilles Debunneb35ab7b2011-12-05 15:54:00 -0800267 public void onPostDraw() {
Romain Guyb025b9c2010-09-16 14:16:48 -0700268 nFinish(mRenderer);
269 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700270
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000271 private static native void nFinish(long renderer);
Romain Guyb025b9c2010-09-16 14:16:48 -0700272
Romain Guy530041d2012-01-25 18:56:29 -0800273 /**
274 * Returns the size of the stencil buffer required by the underlying
275 * implementation.
276 *
277 * @return The minimum number of bits the stencil buffer must. Always >= 0.
278 *
279 * @hide
280 */
281 public static int getStencilSize() {
282 return nGetStencilSize();
283 }
284
285 private static native int nGetStencilSize();
286
287 ///////////////////////////////////////////////////////////////////////////
288 // Functor
289 ///////////////////////////////////////////////////////////////////////////
290
Romain Guyda8532c2010-08-31 11:50:35 -0700291 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000292 public int callDrawGLFunction(long drawGLFunction) {
Chet Haasedaf98e92011-01-10 14:10:36 -0800293 return nCallDrawGLFunction(mRenderer, drawGLFunction);
294 }
295
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000296 private static native int nCallDrawGLFunction(long renderer, long drawGLFunction);
Chet Haasedaf98e92011-01-10 14:10:36 -0800297
Romain Guy8f3b8e32012-03-27 16:33:45 -0700298 @Override
299 public int invokeFunctors(Rect dirty) {
300 return nInvokeFunctors(mRenderer, dirty);
301 }
302
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000303 private static native int nInvokeFunctors(long renderer, Rect dirty);
Romain Guy8f3b8e32012-03-27 16:33:45 -0700304
Romain Guyba6be8a2012-04-23 18:22:09 -0700305 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000306 public void detachFunctor(long functor) {
Romain Guyba6be8a2012-04-23 18:22:09 -0700307 nDetachFunctor(mRenderer, functor);
308 }
309
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000310 private static native void nDetachFunctor(long renderer, long functor);
Romain Guyba6be8a2012-04-23 18:22:09 -0700311
312 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000313 public void attachFunctor(long functor) {
Romain Guyba6be8a2012-04-23 18:22:09 -0700314 nAttachFunctor(mRenderer, functor);
315 }
316
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000317 private static native void nAttachFunctor(long renderer, long functor);
Romain Guyba6be8a2012-04-23 18:22:09 -0700318
Romain Guybdf76092011-07-18 15:00:43 -0700319 ///////////////////////////////////////////////////////////////////////////
320 // Memory
321 ///////////////////////////////////////////////////////////////////////////
322
323 /**
Romain Guy6d7475d2011-07-27 16:28:21 -0700324 * Must match Caches::FlushMode values
325 *
Romain Guybdf76092011-07-18 15:00:43 -0700326 * @see #flushCaches(int)
327 */
Romain Guy3b748a42013-04-17 18:54:38 -0700328 static final int FLUSH_CACHES_LAYERS = 0;
Romain Guy6d7475d2011-07-27 16:28:21 -0700329
330 /**
331 * Must match Caches::FlushMode values
332 *
333 * @see #flushCaches(int)
334 */
Romain Guy3b748a42013-04-17 18:54:38 -0700335 static final int FLUSH_CACHES_MODERATE = 1;
Romain Guybdf76092011-07-18 15:00:43 -0700336
337 /**
Romain Guy6d7475d2011-07-27 16:28:21 -0700338 * Must match Caches::FlushMode values
339 *
Romain Guybdf76092011-07-18 15:00:43 -0700340 * @see #flushCaches(int)
341 */
Romain Guy3b748a42013-04-17 18:54:38 -0700342 static final int FLUSH_CACHES_FULL = 2;
Romain Guybdf76092011-07-18 15:00:43 -0700343
344 /**
345 * Flush caches to reclaim as much memory as possible. The amount of memory
346 * to reclaim is indicate by the level parameter.
347 *
348 * The level can be one of {@link #FLUSH_CACHES_MODERATE} or
349 * {@link #FLUSH_CACHES_FULL}.
350 *
351 * @param level Hint about the amount of memory to reclaim
Romain Guybdf76092011-07-18 15:00:43 -0700352 */
Romain Guy3b748a42013-04-17 18:54:38 -0700353 static void flushCaches(int level) {
Romain Guybdf76092011-07-18 15:00:43 -0700354 nFlushCaches(level);
355 }
356
357 private static native void nFlushCaches(int level);
358
Romain Guy8ff6b9e2011-11-09 20:10:18 -0800359 /**
360 * Release all resources associated with the underlying caches. This should
361 * only be called after a full flushCaches().
362 *
363 * @hide
364 */
Romain Guy3b748a42013-04-17 18:54:38 -0700365 static void terminateCaches() {
Romain Guy8ff6b9e2011-11-09 20:10:18 -0800366 nTerminateCaches();
367 }
368
369 private static native void nTerminateCaches();
370
Romain Guy3b748a42013-04-17 18:54:38 -0700371 static boolean initCaches() {
372 return nInitCaches();
Romain Guy8ff6b9e2011-11-09 20:10:18 -0800373 }
374
Romain Guy3b748a42013-04-17 18:54:38 -0700375 private static native boolean nInitCaches();
376
377 ///////////////////////////////////////////////////////////////////////////
378 // Atlas
379 ///////////////////////////////////////////////////////////////////////////
380
381 static void initAtlas(GraphicBuffer buffer, int[] map) {
382 nInitAtlas(buffer, map, map.length);
383 }
384
385 private static native void nInitAtlas(GraphicBuffer buffer, int[] map, int count);
386
Romain Guyb051e892010-09-28 19:09:36 -0700387 ///////////////////////////////////////////////////////////////////////////
388 // Display list
389 ///////////////////////////////////////////////////////////////////////////
390
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000391 long getDisplayList(long displayList) {
Jeff Brown162a0212011-07-21 17:02:54 -0700392 return nGetDisplayList(mRenderer, displayList);
Romain Guyb051e892010-09-28 19:09:36 -0700393 }
394
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000395 private static native long nGetDisplayList(long renderer, long displayList);
Romain Guy52036b12013-02-14 18:03:37 -0800396
397 @Override
Chet Haase1271e2c2012-04-20 09:54:27 -0700398 public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
Chris Craik54389792013-12-20 13:28:11 -0800399 return nDrawDisplayList(mRenderer, displayList.getNativeDisplayList(),
Chet Haase1271e2c2012-04-20 09:54:27 -0700400 dirty, flags);
Romain Guyb051e892010-09-28 19:09:36 -0700401 }
402
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000403 private static native int nDrawDisplayList(long renderer, long displayList,
Chet Haase1271e2c2012-04-20 09:54:27 -0700404 Rect dirty, int flags);
Romain Guyda8532c2010-08-31 11:50:35 -0700405
Romain Guye4d01122010-06-16 18:44:05 -0700406 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800407 // Hardware layer
408 ///////////////////////////////////////////////////////////////////////////
409
Romain Guyada830f2011-01-13 12:13:20 -0800410 void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
Chris Craika4e16c52013-03-22 10:00:48 -0700411 layer.setLayerPaint(paint);
412
Romain Guy6c319ca2011-01-11 14:29:25 -0800413 final GLES20Layer glLayer = (GLES20Layer) layer;
Chris Craika4e16c52013-03-22 10:00:48 -0700414 nDrawLayer(mRenderer, glLayer.getLayer(), x, y);
Romain Guy6c319ca2011-01-11 14:29:25 -0800415 }
416
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000417 private static native void nDrawLayer(long renderer, long layer, float x, float y);
Romain Guyaa6c24c2011-04-28 18:40:04 -0700418
Romain Guy6c319ca2011-01-11 14:29:25 -0800419 void interrupt() {
420 nInterrupt(mRenderer);
421 }
422
423 void resume() {
424 nResume(mRenderer);
425 }
426
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000427 private static native void nInterrupt(long renderer);
428 private static native void nResume(long renderer);
Romain Guy6c319ca2011-01-11 14:29:25 -0800429
430 ///////////////////////////////////////////////////////////////////////////
Romain Guy6410c0a2013-06-17 11:21:58 -0700431 // Support
432 ///////////////////////////////////////////////////////////////////////////
433
434 private Rect getInternalClipBounds() {
435 if (mClipBounds == null) mClipBounds = new Rect();
436 return mClipBounds;
437 }
438
439
440 private RectF getPathBounds() {
441 if (mPathBounds == null) mPathBounds = new RectF();
442 return mPathBounds;
443 }
444
445 private float[] getPointStorage() {
446 if (mPoint == null) mPoint = new float[2];
447 return mPoint;
448 }
449
450 private float[] getLineStorage() {
451 if (mLine == null) mLine = new float[4];
452 return mLine;
453 }
454
455 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700456 // Clipping
457 ///////////////////////////////////////////////////////////////////////////
458
459 @Override
460 public boolean clipPath(Path path) {
Romain Guy735738c2012-12-03 12:34:51 -0800461 return nClipPath(mRenderer, path.mNativePath, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700462 }
463
464 @Override
465 public boolean clipPath(Path path, Region.Op op) {
Romain Guy735738c2012-12-03 12:34:51 -0800466 return nClipPath(mRenderer, path.mNativePath, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700467 }
468
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000469 private static native boolean nClipPath(long renderer, long path, int op);
Romain Guy735738c2012-12-03 12:34:51 -0800470
Romain Guye4d01122010-06-16 18:44:05 -0700471 @Override
472 public boolean clipRect(float left, float top, float right, float bottom) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700473 return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700474 }
Romain Guybb9524b2010-06-22 18:56:38 -0700475
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000476 private static native boolean nClipRect(long renderer, float left, float top,
Romain Guy079ba2c2010-07-16 14:12:24 -0700477 float right, float bottom, int op);
Romain Guye4d01122010-06-16 18:44:05 -0700478
479 @Override
480 public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700481 return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700482 }
483
484 @Override
485 public boolean clipRect(int left, int top, int right, int bottom) {
Chet Haasedaf98e92011-01-10 14:10:36 -0800486 return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700487 }
Romain Guybb9524b2010-06-22 18:56:38 -0700488
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000489 private static native boolean nClipRect(long renderer, int left, int top,
Romain Guy735738c2012-12-03 12:34:51 -0800490 int right, int bottom, int op);
Romain Guye4d01122010-06-16 18:44:05 -0700491
492 @Override
493 public boolean clipRect(Rect rect) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700494 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
495 Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700496 }
497
498 @Override
499 public boolean clipRect(Rect rect, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700500 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700501 }
502
503 @Override
504 public boolean clipRect(RectF rect) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700505 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
506 Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700507 }
508
509 @Override
510 public boolean clipRect(RectF rect, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700511 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700512 }
513
514 @Override
515 public boolean clipRegion(Region region) {
Romain Guy735738c2012-12-03 12:34:51 -0800516 return nClipRegion(mRenderer, region.mNativeRegion, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700517 }
518
519 @Override
520 public boolean clipRegion(Region region, Region.Op op) {
Romain Guy735738c2012-12-03 12:34:51 -0800521 return nClipRegion(mRenderer, region.mNativeRegion, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700522 }
523
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000524 private static native boolean nClipRegion(long renderer, long region, int op);
Romain Guy735738c2012-12-03 12:34:51 -0800525
Romain Guye4d01122010-06-16 18:44:05 -0700526 @Override
527 public boolean getClipBounds(Rect bounds) {
Romain Guy9d5316e2010-06-24 19:30:36 -0700528 return nGetClipBounds(mRenderer, bounds);
Romain Guye4d01122010-06-16 18:44:05 -0700529 }
530
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000531 private static native boolean nGetClipBounds(long renderer, Rect bounds);
Romain Guy9d5316e2010-06-24 19:30:36 -0700532
Romain Guye4d01122010-06-16 18:44:05 -0700533 @Override
534 public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
Derek Sollenbergerca79cf62012-08-14 16:44:52 -0400535 return nQuickReject(mRenderer, left, top, right, bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700536 }
Romain Guyc7d53492010-06-25 13:41:57 -0700537
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000538 private static native boolean nQuickReject(long renderer, float left, float top,
Derek Sollenbergerca79cf62012-08-14 16:44:52 -0400539 float right, float bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700540
541 @Override
542 public boolean quickReject(Path path, EdgeType type) {
Romain Guy6410c0a2013-06-17 11:21:58 -0700543 RectF pathBounds = getPathBounds();
544 path.computeBounds(pathBounds, true);
545 return nQuickReject(mRenderer, pathBounds.left, pathBounds.top,
546 pathBounds.right, pathBounds.bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700547 }
548
549 @Override
550 public boolean quickReject(RectF rect, EdgeType type) {
Derek Sollenbergerca79cf62012-08-14 16:44:52 -0400551 return nQuickReject(mRenderer, rect.left, rect.top, rect.right, rect.bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700552 }
553
554 ///////////////////////////////////////////////////////////////////////////
555 // Transformations
556 ///////////////////////////////////////////////////////////////////////////
557
558 @Override
559 public void translate(float dx, float dy) {
Romain Guy807daf72011-01-18 11:19:19 -0800560 if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy);
Romain Guye4d01122010-06-16 18:44:05 -0700561 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700562
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000563 private static native void nTranslate(long renderer, float dx, float dy);
Romain Guye4d01122010-06-16 18:44:05 -0700564
565 @Override
566 public void skew(float sx, float sy) {
Romain Guy807daf72011-01-18 11:19:19 -0800567 nSkew(mRenderer, sx, sy);
Romain Guye4d01122010-06-16 18:44:05 -0700568 }
569
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000570 private static native void nSkew(long renderer, float sx, float sy);
Romain Guy807daf72011-01-18 11:19:19 -0800571
Romain Guye4d01122010-06-16 18:44:05 -0700572 @Override
573 public void rotate(float degrees) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700574 nRotate(mRenderer, degrees);
Romain Guye4d01122010-06-16 18:44:05 -0700575 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700576
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000577 private static native void nRotate(long renderer, float degrees);
Romain Guye4d01122010-06-16 18:44:05 -0700578
579 @Override
580 public void scale(float sx, float sy) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700581 nScale(mRenderer, sx, sy);
Romain Guye4d01122010-06-16 18:44:05 -0700582 }
Romain Guye4d01122010-06-16 18:44:05 -0700583
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000584 private static native void nScale(long renderer, float sx, float sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700585
Romain Guye4d01122010-06-16 18:44:05 -0700586 @Override
587 public void setMatrix(Matrix matrix) {
Romain Guye7078592011-10-28 14:32:20 -0700588 nSetMatrix(mRenderer, matrix == null ? 0 : matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700589 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700590
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000591 private static native void nSetMatrix(long renderer, long matrix);
Romain Guye4d01122010-06-16 18:44:05 -0700592
Romain Guy5ff9df62012-01-23 17:09:05 -0800593 @SuppressWarnings("deprecation")
Romain Guye4d01122010-06-16 18:44:05 -0700594 @Override
Romain Guyf6a11b82010-06-23 17:47:49 -0700595 public void getMatrix(Matrix matrix) {
596 nGetMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700597 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700598
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000599 private static native void nGetMatrix(long renderer, long matrix);
Romain Guye4d01122010-06-16 18:44:05 -0700600
601 @Override
602 public void concat(Matrix matrix) {
Romain Guy4e7b7722013-07-16 13:47:01 -0700603 if (matrix != null) nConcatMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700604 }
605
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000606 private static native void nConcatMatrix(long renderer, long matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700607
Romain Guye4d01122010-06-16 18:44:05 -0700608 ///////////////////////////////////////////////////////////////////////////
609 // State management
610 ///////////////////////////////////////////////////////////////////////////
611
612 @Override
613 public int save() {
Romain Guy8aef54f2010-09-01 15:13:49 -0700614 return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
Romain Guye4d01122010-06-16 18:44:05 -0700615 }
Romain Guybb9524b2010-06-22 18:56:38 -0700616
Romain Guye4d01122010-06-16 18:44:05 -0700617 @Override
618 public int save(int saveFlags) {
Romain Guybb9524b2010-06-22 18:56:38 -0700619 return nSave(mRenderer, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700620 }
621
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000622 private static native int nSave(long renderer, int flags);
Romain Guybb9524b2010-06-22 18:56:38 -0700623
Romain Guye4d01122010-06-16 18:44:05 -0700624 @Override
625 public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
Romain Guy189887e2011-08-25 11:45:13 -0700626 if (bounds != null) {
627 return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
628 }
629
Romain Guy445c83c2012-02-16 16:43:07 -0800630 int count;
Romain Guy189887e2011-08-25 11:45:13 -0700631 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800632 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000633 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guy445c83c2012-02-16 16:43:07 -0800634 count = nSaveLayer(mRenderer, nativePaint, saveFlags);
635 } finally {
636 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
637 }
Romain Guy189887e2011-08-25 11:45:13 -0700638 return count;
Romain Guye4d01122010-06-16 18:44:05 -0700639 }
640
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000641 private static native int nSaveLayer(long renderer, long paint, int saveFlags);
Romain Guy189887e2011-08-25 11:45:13 -0700642
Romain Guye4d01122010-06-16 18:44:05 -0700643 @Override
644 public int saveLayer(float left, float top, float right, float bottom, Paint paint,
645 int saveFlags) {
Romain Guy01d58e42011-01-19 21:54:02 -0800646 if (left < right && top < bottom) {
Romain Guy445c83c2012-02-16 16:43:07 -0800647 int count;
Romain Guya168d732011-03-18 16:50:13 -0700648 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800649 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000650 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guy445c83c2012-02-16 16:43:07 -0800651 count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
652 } finally {
653 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
654 }
Romain Guy01d58e42011-01-19 21:54:02 -0800655 return count;
656 }
657 return save(saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700658 }
659
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000660 private static native int nSaveLayer(long renderer, float left, float top,
661 float right, float bottom, long paint, int saveFlags);
Romain Guybd6b79b2010-06-26 00:13:53 -0700662
Romain Guye4d01122010-06-16 18:44:05 -0700663 @Override
664 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
Romain Guy189887e2011-08-25 11:45:13 -0700665 if (bounds != null) {
666 return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
667 alpha, saveFlags);
668 }
669 return nSaveLayerAlpha(mRenderer, alpha, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700670 }
671
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000672 private static native int nSaveLayerAlpha(long renderer, int alpha, int saveFlags);
Romain Guy189887e2011-08-25 11:45:13 -0700673
Romain Guye4d01122010-06-16 18:44:05 -0700674 @Override
675 public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
676 int saveFlags) {
Romain Guy01d58e42011-01-19 21:54:02 -0800677 if (left < right && top < bottom) {
678 return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
679 }
680 return save(saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700681 }
682
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000683 private static native int nSaveLayerAlpha(long renderer, float left, float top, float right,
Romain Guybd6b79b2010-06-26 00:13:53 -0700684 float bottom, int alpha, int saveFlags);
685
Romain Guye4d01122010-06-16 18:44:05 -0700686 @Override
687 public void restore() {
Romain Guybb9524b2010-06-22 18:56:38 -0700688 nRestore(mRenderer);
Romain Guye4d01122010-06-16 18:44:05 -0700689 }
Romain Guybb9524b2010-06-22 18:56:38 -0700690
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000691 private static native void nRestore(long renderer);
Romain Guye4d01122010-06-16 18:44:05 -0700692
693 @Override
694 public void restoreToCount(int saveCount) {
Romain Guybb9524b2010-06-22 18:56:38 -0700695 nRestoreToCount(mRenderer, saveCount);
Romain Guye4d01122010-06-16 18:44:05 -0700696 }
697
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000698 private static native void nRestoreToCount(long renderer, int saveCount);
Romain Guybb9524b2010-06-22 18:56:38 -0700699
Romain Guye4d01122010-06-16 18:44:05 -0700700 @Override
701 public int getSaveCount() {
Romain Guybb9524b2010-06-22 18:56:38 -0700702 return nGetSaveCount(mRenderer);
Romain Guye4d01122010-06-16 18:44:05 -0700703 }
Romain Guybb9524b2010-06-22 18:56:38 -0700704
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000705 private static native int nGetSaveCount(long renderer);
Romain Guye4d01122010-06-16 18:44:05 -0700706
707 ///////////////////////////////////////////////////////////////////////////
708 // Filtering
709 ///////////////////////////////////////////////////////////////////////////
710
711 @Override
712 public void setDrawFilter(DrawFilter filter) {
Romain Guy6926c722010-07-12 20:20:03 -0700713 mFilter = filter;
Romain Guy5ff9df62012-01-23 17:09:05 -0800714 if (filter == null) {
715 nResetPaintFilter(mRenderer);
716 } else if (filter instanceof PaintFlagsDrawFilter) {
717 PaintFlagsDrawFilter flagsFilter = (PaintFlagsDrawFilter) filter;
718 nSetupPaintFilter(mRenderer, flagsFilter.clearBits, flagsFilter.setBits);
719 }
Romain Guye4d01122010-06-16 18:44:05 -0700720 }
721
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000722 private static native void nResetPaintFilter(long renderer);
723 private static native void nSetupPaintFilter(long renderer, int clearBits, int setBits);
Romain Guy5ff9df62012-01-23 17:09:05 -0800724
Romain Guye4d01122010-06-16 18:44:05 -0700725 @Override
726 public DrawFilter getDrawFilter() {
Romain Guy6926c722010-07-12 20:20:03 -0700727 return mFilter;
Romain Guye4d01122010-06-16 18:44:05 -0700728 }
729
730 ///////////////////////////////////////////////////////////////////////////
731 // Drawing
732 ///////////////////////////////////////////////////////////////////////////
733
734 @Override
735 public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
736 Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -0800737 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -0800738 try {
739 nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom,
740 startAngle, sweepAngle, useCenter, paint.mNativePaint);
741 } finally {
742 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
743 }
Romain Guye4d01122010-06-16 18:44:05 -0700744 }
745
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000746 private static native void nDrawArc(long renderer, float left, float top,
Romain Guy7d7b5492011-01-24 16:33:45 -0800747 float right, float bottom, float startAngle, float sweepAngle,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000748 boolean useCenter, long paint);
Romain Guy8b2f5262011-01-23 16:15:02 -0800749
Romain Guye4d01122010-06-16 18:44:05 -0700750 @Override
751 public void drawARGB(int a, int r, int g, int b) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700752 drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
Romain Guye4d01122010-06-16 18:44:05 -0700753 }
754
755 @Override
Romain Guyf3187b72013-06-07 12:17:11 -0700756 public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
757 Bitmap bitmap = patch.getBitmap();
Chris Craik1abf5d62013-08-16 12:47:03 -0700758 throwIfCannotDraw(bitmap);
Romain Guyf3187b72013-06-07 12:17:11 -0700759 // Shaders are ignored when drawing patches
760 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
761 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000762 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Chris Craik0c20c382013-07-02 10:48:54 -0700763 nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
Romain Guyf3187b72013-06-07 12:17:11 -0700764 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
765 } finally {
766 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
767 }
768 }
769
770 @Override
Romain Guy3b748a42013-04-17 18:54:38 -0700771 public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
772 Bitmap bitmap = patch.getBitmap();
Chris Craik1abf5d62013-08-16 12:47:03 -0700773 throwIfCannotDraw(bitmap);
Romain Guyd27977d2010-07-14 19:18:51 -0700774 // Shaders are ignored when drawing patches
Romain Guya168d732011-03-18 16:50:13 -0700775 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800776 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000777 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Chris Craik0c20c382013-07-02 10:48:54 -0700778 nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
Romain Guy445c83c2012-02-16 16:43:07 -0800779 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
780 } finally {
781 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
782 }
Romain Guydeba7852010-07-07 17:54:48 -0700783 }
784
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000785 private static native void nDrawPatch(long renderer, long bitmap, byte[] buffer, long chunk,
786 float left, float top, float right, float bottom, long paint);
Romain Guydeba7852010-07-07 17:54:48 -0700787
788 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700789 public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700790 throwIfCannotDraw(bitmap);
Romain Guyd27977d2010-07-14 19:18:51 -0700791 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700792 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800793 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000794 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Chris Craik0c20c382013-07-02 10:48:54 -0700795 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
Romain Guy445c83c2012-02-16 16:43:07 -0800796 } finally {
797 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
798 }
Romain Guye4d01122010-06-16 18:44:05 -0700799 }
800
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000801 private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
802 float left, float top, long paint);
Romain Guydbd77cd2010-07-09 10:36:05 -0700803
Romain Guye4d01122010-06-16 18:44:05 -0700804 @Override
805 public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700806 throwIfCannotDraw(bitmap);
Romain Guyd27977d2010-07-14 19:18:51 -0700807 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700808 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800809 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000810 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Chris Craik0c20c382013-07-02 10:48:54 -0700811 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
812 matrix.native_instance, nativePaint);
Romain Guy445c83c2012-02-16 16:43:07 -0800813 } finally {
814 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
815 }
Romain Guye4d01122010-06-16 18:44:05 -0700816 }
817
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000818 private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
819 long matrix, long paint);
Romain Guyf86ef572010-07-01 11:05:42 -0700820
Romain Guye4d01122010-06-16 18:44:05 -0700821 @Override
822 public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700823 throwIfCannotDraw(bitmap);
Romain Guyd27977d2010-07-14 19:18:51 -0700824 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700825 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800826 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000827 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guy694b5192010-07-21 21:33:20 -0700828
Romain Guy445c83c2012-02-16 16:43:07 -0800829 int left, top, right, bottom;
830 if (src == null) {
831 left = top = 0;
832 right = bitmap.getWidth();
833 bottom = bitmap.getHeight();
834 } else {
835 left = src.left;
836 right = src.right;
837 top = src.top;
838 bottom = src.bottom;
839 }
840
Chris Craik0c20c382013-07-02 10:48:54 -0700841 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
Romain Guy445c83c2012-02-16 16:43:07 -0800842 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
843 } finally {
844 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy694b5192010-07-21 21:33:20 -0700845 }
Romain Guye4d01122010-06-16 18:44:05 -0700846 }
847
848 @Override
849 public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700850 throwIfCannotDraw(bitmap);
Romain Guyd27977d2010-07-14 19:18:51 -0700851 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700852 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800853 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000854 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guy445c83c2012-02-16 16:43:07 -0800855
856 float left, top, right, bottom;
857 if (src == null) {
858 left = top = 0;
859 right = bitmap.getWidth();
860 bottom = bitmap.getHeight();
861 } else {
862 left = src.left;
863 right = src.right;
864 top = src.top;
865 bottom = src.bottom;
866 }
867
Chris Craik0c20c382013-07-02 10:48:54 -0700868 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
Romain Guy445c83c2012-02-16 16:43:07 -0800869 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
870 } finally {
871 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guyff98fa52011-11-28 09:35:09 -0800872 }
Romain Guye4d01122010-06-16 18:44:05 -0700873 }
874
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000875 private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
Romain Guyce0537b2010-06-29 21:05:21 -0700876 float srcLeft, float srcTop, float srcRight, float srcBottom,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000877 float left, float top, float right, float bottom, long paint);
Romain Guyce0537b2010-06-29 21:05:21 -0700878
Romain Guye4d01122010-06-16 18:44:05 -0700879 @Override
880 public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
881 int width, int height, boolean hasAlpha, Paint paint) {
Romain Guye651cc62012-05-14 19:44:40 -0700882 if (width < 0) {
883 throw new IllegalArgumentException("width must be >= 0");
884 }
885
886 if (height < 0) {
887 throw new IllegalArgumentException("height must be >= 0");
888 }
889
890 if (Math.abs(stride) < width) {
891 throw new IllegalArgumentException("abs(stride) must be >= width");
892 }
893
894 int lastScanline = offset + (height - 1) * stride;
895 int length = colors.length;
896
897 if (offset < 0 || (offset + width > length) || lastScanline < 0 ||
898 (lastScanline + width > length)) {
899 throw new ArrayIndexOutOfBoundsException();
900 }
901
Romain Guyd27977d2010-07-14 19:18:51 -0700902 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700903 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800904 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000905 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guye651cc62012-05-14 19:44:40 -0700906 nDrawBitmap(mRenderer, colors, offset, stride, x, y,
907 width, height, hasAlpha, nativePaint);
Romain Guy445c83c2012-02-16 16:43:07 -0800908 } finally {
909 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
910 }
Romain Guye4d01122010-06-16 18:44:05 -0700911 }
912
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000913 private static native void nDrawBitmap(long renderer, int[] colors, int offset, int stride,
914 float x, float y, int width, int height, boolean hasAlpha, long nativePaint);
Romain Guye651cc62012-05-14 19:44:40 -0700915
Romain Guye4d01122010-06-16 18:44:05 -0700916 @Override
917 public void drawBitmap(int[] colors, int offset, int stride, int x, int y,
918 int width, int height, boolean hasAlpha, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700919 // Shaders are ignored when drawing bitmaps
Romain Guyce0537b2010-06-29 21:05:21 -0700920 drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700921 }
922
923 @Override
924 public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
925 int vertOffset, int[] colors, int colorOffset, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700926 throwIfCannotDraw(bitmap);
Romain Guy5a7b4662011-01-20 19:09:30 -0800927 if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
928 throw new ArrayIndexOutOfBoundsException();
929 }
930
931 if (meshWidth == 0 || meshHeight == 0) {
932 return;
933 }
934
935 final int count = (meshWidth + 1) * (meshHeight + 1);
936 checkRange(verts.length, vertOffset, count * 2);
937
Romain Guyff316ec2013-02-13 18:39:43 -0800938 if (colors != null) {
939 checkRange(colors.length, colorOffset, count);
940 }
Romain Guy5a7b4662011-01-20 19:09:30 -0800941
Romain Guya168d732011-03-18 16:50:13 -0700942 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guy445c83c2012-02-16 16:43:07 -0800943 try {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000944 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Chris Craik0c20c382013-07-02 10:48:54 -0700945 nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
Romain Guy445c83c2012-02-16 16:43:07 -0800946 verts, vertOffset, colors, colorOffset, nativePaint);
947 } finally {
948 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
949 }
Romain Guye4d01122010-06-16 18:44:05 -0700950 }
951
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000952 private static native void nDrawBitmapMesh(long renderer, long bitmap, byte[] buffer,
Romain Guy5a7b4662011-01-20 19:09:30 -0800953 int meshWidth, int meshHeight, float[] verts, int vertOffset,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000954 int[] colors, int colorOffset, long paint);
Romain Guy5a7b4662011-01-20 19:09:30 -0800955
Romain Guye4d01122010-06-16 18:44:05 -0700956 @Override
957 public void drawCircle(float cx, float cy, float radius, Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -0800958 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -0800959 try {
960 nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
961 } finally {
962 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
963 }
Romain Guye4d01122010-06-16 18:44:05 -0700964 }
965
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000966 private static native void nDrawCircle(long renderer, float cx, float cy,
967 float radius, long paint);
Romain Guy01d58e42011-01-19 21:54:02 -0800968
Romain Guye4d01122010-06-16 18:44:05 -0700969 @Override
970 public void drawColor(int color) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700971 drawColor(color, PorterDuff.Mode.SRC_OVER);
Romain Guye4d01122010-06-16 18:44:05 -0700972 }
973
974 @Override
975 public void drawColor(int color, PorterDuff.Mode mode) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700976 nDrawColor(mRenderer, color, mode.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700977 }
Romain Guy85bf02f2010-06-22 13:11:24 -0700978
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000979 private static native void nDrawColor(long renderer, int color, int mode);
Romain Guye4d01122010-06-16 18:44:05 -0700980
981 @Override
982 public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
Romain Guy6410c0a2013-06-17 11:21:58 -0700983 float[] line = getLineStorage();
984 line[0] = startX;
985 line[1] = startY;
986 line[2] = stopX;
987 line[3] = stopY;
988 drawLines(line, 0, 4, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700989 }
990
991 @Override
992 public void drawLines(float[] pts, int offset, int count, Paint paint) {
Chris Craik5d116762013-02-19 17:49:31 -0800993 if (count < 4) return;
994
Romain Guy759ea802010-09-16 20:49:46 -0700995 if ((offset | count) < 0 || offset + count > pts.length) {
996 throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
997 }
Romain Guy765dcf32012-02-27 13:28:22 -0800998 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -0800999 try {
1000 nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
1001 } finally {
1002 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1003 }
Romain Guye4d01122010-06-16 18:44:05 -07001004 }
1005
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001006 private static native void nDrawLines(long renderer, float[] points,
1007 int offset, int count, long paint);
Romain Guy759ea802010-09-16 20:49:46 -07001008
Romain Guye4d01122010-06-16 18:44:05 -07001009 @Override
1010 public void drawLines(float[] pts, Paint paint) {
Romain Guy759ea802010-09-16 20:49:46 -07001011 drawLines(pts, 0, pts.length, paint);
Romain Guye4d01122010-06-16 18:44:05 -07001012 }
1013
1014 @Override
1015 public void drawOval(RectF oval, Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -08001016 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -08001017 try {
1018 nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
1019 } finally {
1020 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1021 }
Romain Guye4d01122010-06-16 18:44:05 -07001022 }
1023
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001024 private static native void nDrawOval(long renderer, float left, float top,
1025 float right, float bottom, long paint);
Romain Guyc1cd9ba32011-01-23 14:18:41 -08001026
Romain Guye4d01122010-06-16 18:44:05 -07001027 @Override
1028 public void drawPaint(Paint paint) {
Romain Guy6410c0a2013-06-17 11:21:58 -07001029 final Rect r = getInternalClipBounds();
Romain Guy6926c722010-07-12 20:20:03 -07001030 nGetClipBounds(mRenderer, r);
1031 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -07001032 }
1033
1034 @Override
1035 public void drawPath(Path path, Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -08001036 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -08001037 try {
1038 if (path.isSimplePath) {
1039 if (path.rects != null) {
1040 nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
1041 }
1042 } else {
1043 nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
Romain Guya48a1a82010-08-10 14:59:15 -07001044 }
Romain Guy445c83c2012-02-16 16:43:07 -08001045 } finally {
1046 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guya48a1a82010-08-10 14:59:15 -07001047 }
Romain Guye4d01122010-06-16 18:44:05 -07001048 }
1049
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001050 private static native void nDrawPath(long renderer, long path, long paint);
1051 private static native void nDrawRects(long renderer, long region, long paint);
Romain Guy7fbcc042010-08-04 15:40:07 -07001052
Romain Guy672433d2013-01-04 19:05:13 -08001053 void drawRects(float[] rects, int count, Paint paint) {
1054 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
1055 try {
1056 nDrawRects(mRenderer, rects, count, paint.mNativePaint);
1057 } finally {
1058 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1059 }
1060 }
1061
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001062 private static native void nDrawRects(long renderer, float[] rects, int count, long paint);
Romain Guy672433d2013-01-04 19:05:13 -08001063
Romain Guye4d01122010-06-16 18:44:05 -07001064 @Override
1065 public void drawPicture(Picture picture) {
Romain Guyf9d9c062012-01-19 16:53:41 -08001066 if (picture.createdFromStream) {
1067 return;
1068 }
1069
Romain Guy75582e82012-01-18 18:13:35 -08001070 picture.endRecording();
1071 // TODO: Implement rendering
Romain Guye4d01122010-06-16 18:44:05 -07001072 }
1073
1074 @Override
1075 public void drawPicture(Picture picture, Rect dst) {
Romain Guyf9d9c062012-01-19 16:53:41 -08001076 if (picture.createdFromStream) {
1077 return;
1078 }
1079
Romain Guy75582e82012-01-18 18:13:35 -08001080 save();
1081 translate(dst.left, dst.top);
1082 if (picture.getWidth() > 0 && picture.getHeight() > 0) {
1083 scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
1084 }
1085 drawPicture(picture);
1086 restore();
Romain Guye4d01122010-06-16 18:44:05 -07001087 }
1088
1089 @Override
1090 public void drawPicture(Picture picture, RectF dst) {
Romain Guyf9d9c062012-01-19 16:53:41 -08001091 if (picture.createdFromStream) {
1092 return;
1093 }
1094
Romain Guy75582e82012-01-18 18:13:35 -08001095 save();
1096 translate(dst.left, dst.top);
1097 if (picture.getWidth() > 0 && picture.getHeight() > 0) {
1098 scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
1099 }
1100 drawPicture(picture);
1101 restore();
Romain Guye4d01122010-06-16 18:44:05 -07001102 }
1103
1104 @Override
1105 public void drawPoint(float x, float y, Paint paint) {
Romain Guy6410c0a2013-06-17 11:21:58 -07001106 float[] point = getPointStorage();
1107 point[0] = x;
1108 point[1] = y;
1109 drawPoints(point, 0, 2, paint);
Romain Guye4d01122010-06-16 18:44:05 -07001110 }
1111
1112 @Override
1113 public void drawPoints(float[] pts, Paint paint) {
Romain Guyed6fcb02011-03-21 13:11:28 -07001114 drawPoints(pts, 0, pts.length, paint);
Romain Guye4d01122010-06-16 18:44:05 -07001115 }
1116
1117 @Override
Romain Guyed6fcb02011-03-21 13:11:28 -07001118 public void drawPoints(float[] pts, int offset, int count, Paint paint) {
Chris Craik5d116762013-02-19 17:49:31 -08001119 if (count < 2) return;
1120
Romain Guy765dcf32012-02-27 13:28:22 -08001121 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -08001122 try {
1123 nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
1124 } finally {
1125 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1126 }
Romain Guyed6fcb02011-03-21 13:11:28 -07001127 }
1128
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001129 private static native void nDrawPoints(long renderer, float[] points,
1130 int offset, int count, long paint);
Romain Guyed6fcb02011-03-21 13:11:28 -07001131
Romain Guy5ff9df62012-01-23 17:09:05 -08001132 @SuppressWarnings("deprecation")
Romain Guyed6fcb02011-03-21 13:11:28 -07001133 @Override
Romain Guye4d01122010-06-16 18:44:05 -07001134 public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
Romain Guyeb9a5362012-01-17 17:39:26 -08001135 if (index < 0 || index + count > text.length || count * 2 > pos.length) {
1136 throw new IndexOutOfBoundsException();
1137 }
1138
1139 int modifiers = setupModifiers(paint);
1140 try {
1141 nDrawPosText(mRenderer, text, index, count, pos, paint.mNativePaint);
1142 } finally {
1143 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1144 }
Romain Guye4d01122010-06-16 18:44:05 -07001145 }
1146
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001147 private static native void nDrawPosText(long renderer, char[] text, int index, int count,
1148 float[] pos, long paint);
Romain Guyeb9a5362012-01-17 17:39:26 -08001149
Romain Guy5ff9df62012-01-23 17:09:05 -08001150 @SuppressWarnings("deprecation")
Romain Guye4d01122010-06-16 18:44:05 -07001151 @Override
1152 public void drawPosText(String text, float[] pos, Paint paint) {
Romain Guyeb9a5362012-01-17 17:39:26 -08001153 if (text.length() * 2 > pos.length) {
1154 throw new ArrayIndexOutOfBoundsException();
1155 }
1156
1157 int modifiers = setupModifiers(paint);
1158 try {
1159 nDrawPosText(mRenderer, text, 0, text.length(), pos, paint.mNativePaint);
1160 } finally {
1161 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1162 }
Romain Guye4d01122010-06-16 18:44:05 -07001163 }
1164
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001165 private static native void nDrawPosText(long renderer, String text, int start, int end,
1166 float[] pos, long paint);
Romain Guyeb9a5362012-01-17 17:39:26 -08001167
Romain Guye4d01122010-06-16 18:44:05 -07001168 @Override
1169 public void drawRect(float left, float top, float right, float bottom, Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -08001170 if (left == right || top == bottom) return;
1171 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -08001172 try {
1173 nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
1174 } finally {
1175 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1176 }
Romain Guye4d01122010-06-16 18:44:05 -07001177 }
1178
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001179 private static native void nDrawRect(long renderer, float left, float top,
1180 float right, float bottom, long paint);
Romain Guyc7d53492010-06-25 13:41:57 -07001181
Romain Guye4d01122010-06-16 18:44:05 -07001182 @Override
1183 public void drawRect(Rect r, Paint paint) {
Romain Guyc7d53492010-06-25 13:41:57 -07001184 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -07001185 }
1186
1187 @Override
Romain Guyc7d53492010-06-25 13:41:57 -07001188 public void drawRect(RectF r, Paint paint) {
1189 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -07001190 }
1191
1192 @Override
1193 public void drawRGB(int r, int g, int b) {
Romain Guy85bf02f2010-06-22 13:11:24 -07001194 drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
Romain Guye4d01122010-06-16 18:44:05 -07001195 }
1196
1197 @Override
1198 public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -08001199 int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
Romain Guy445c83c2012-02-16 16:43:07 -08001200 try {
1201 nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
1202 rx, ry, paint.mNativePaint);
1203 } finally {
1204 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1205 }
Romain Guye4d01122010-06-16 18:44:05 -07001206 }
1207
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001208 private static native void nDrawRoundRect(long renderer, float left, float top,
1209 float right, float bottom, float rx, float y, long paint);
Romain Guy01d58e42011-01-19 21:54:02 -08001210
Romain Guye4d01122010-06-16 18:44:05 -07001211 @Override
1212 public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
Romain Guya1db5742010-07-20 13:09:13 -07001213 if ((index | count | (index + count) | (text.length - index - count)) < 0) {
1214 throw new IndexOutOfBoundsException();
1215 }
Romain Guy61c8c9c2010-08-09 20:48:09 -07001216
Romain Guya168d732011-03-18 16:50:13 -07001217 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001218 try {
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001219 nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001220 } finally {
Romain Guya168d732011-03-18 16:50:13 -07001221 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001222 }
Romain Guye4d01122010-06-16 18:44:05 -07001223 }
Romain Guya1db5742010-07-20 13:09:13 -07001224
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001225 private static native void nDrawText(long renderer, char[] text, int index, int count,
1226 float x, float y, int bidiFlags, long paint);
Romain Guye4d01122010-06-16 18:44:05 -07001227
1228 @Override
1229 public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -07001230 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001231 try {
1232 if (text instanceof String || text instanceof SpannedString ||
1233 text instanceof SpannableString) {
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001234 nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
1235 paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001236 } else if (text instanceof GraphicsOperations) {
1237 ((GraphicsOperations) text).drawText(this, start, end, x, y,
1238 paint);
1239 } else {
1240 char[] buf = TemporaryBuffer.obtain(end - start);
1241 TextUtils.getChars(text, start, end, buf, 0);
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001242 nDrawText(mRenderer, buf, 0, end - start, x, y,
1243 paint.mBidiFlags, paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001244 TemporaryBuffer.recycle(buf);
1245 }
1246 } finally {
Romain Guya168d732011-03-18 16:50:13 -07001247 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guya1db5742010-07-20 13:09:13 -07001248 }
Romain Guye4d01122010-06-16 18:44:05 -07001249 }
1250
1251 @Override
1252 public void drawText(String text, int start, int end, float x, float y, Paint paint) {
Romain Guya1db5742010-07-20 13:09:13 -07001253 if ((start | end | (end - start) | (text.length() - end)) < 0) {
1254 throw new IndexOutOfBoundsException();
1255 }
Romain Guy61c8c9c2010-08-09 20:48:09 -07001256
Romain Guya168d732011-03-18 16:50:13 -07001257 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001258 try {
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001259 nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001260 } finally {
Romain Guya168d732011-03-18 16:50:13 -07001261 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001262 }
Romain Guye4d01122010-06-16 18:44:05 -07001263 }
1264
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001265 private static native void nDrawText(long renderer, String text, int start, int end,
1266 float x, float y, int bidiFlags, long paint);
Romain Guya1db5742010-07-20 13:09:13 -07001267
Romain Guye4d01122010-06-16 18:44:05 -07001268 @Override
1269 public void drawText(String text, float x, float y, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -07001270 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001271 try {
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001272 nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags,
1273 paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001274 } finally {
Romain Guya168d732011-03-18 16:50:13 -07001275 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001276 }
Romain Guye4d01122010-06-16 18:44:05 -07001277 }
1278
1279 @Override
1280 public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
1281 float vOffset, Paint paint) {
Romain Guy325740f2012-02-24 16:48:34 -08001282 if (index < 0 || index + count > text.length) {
1283 throw new ArrayIndexOutOfBoundsException();
1284 }
1285
1286 int modifiers = setupModifiers(paint);
1287 try {
1288 nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001289 paint.mBidiFlags, paint.mNativePaint);
Romain Guy325740f2012-02-24 16:48:34 -08001290 } finally {
1291 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1292 }
Romain Guye4d01122010-06-16 18:44:05 -07001293 }
1294
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001295 private static native void nDrawTextOnPath(long renderer, char[] text, int index, int count,
1296 long path, float hOffset, float vOffset, int bidiFlags, long nativePaint);
Romain Guy325740f2012-02-24 16:48:34 -08001297
Romain Guye4d01122010-06-16 18:44:05 -07001298 @Override
1299 public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
Romain Guy325740f2012-02-24 16:48:34 -08001300 if (text.length() == 0) return;
1301
1302 int modifiers = setupModifiers(paint);
1303 try {
1304 nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001305 paint.mBidiFlags, paint.mNativePaint);
Romain Guy325740f2012-02-24 16:48:34 -08001306 } finally {
1307 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
1308 }
Romain Guye4d01122010-06-16 18:44:05 -07001309 }
1310
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001311 private static native void nDrawTextOnPath(long renderer, String text, int start, int end,
1312 long path, float hOffset, float vOffset, int bidiFlags, long nativePaint);
Romain Guy325740f2012-02-24 16:48:34 -08001313
Romain Guye4d01122010-06-16 18:44:05 -07001314 @Override
1315 public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001316 float x, float y, int dir, Paint paint) {
Romain Guy61c8c9c2010-08-09 20:48:09 -07001317 if ((index | count | text.length - index - count) < 0) {
1318 throw new IndexOutOfBoundsException();
1319 }
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001320 if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) {
1321 throw new IllegalArgumentException("Unknown direction: " + dir);
1322 }
Romain Guy61c8c9c2010-08-09 20:48:09 -07001323
Romain Guya168d732011-03-18 16:50:13 -07001324 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001325 try {
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001326 nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir,
Romain Guy61c8c9c2010-08-09 20:48:09 -07001327 paint.mNativePaint);
1328 } finally {
Romain Guya168d732011-03-18 16:50:13 -07001329 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001330 }
Romain Guye4d01122010-06-16 18:44:05 -07001331 }
1332
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001333 private static native void nDrawTextRun(long renderer, char[] text, int index, int count,
1334 int contextIndex, int contextCount, float x, float y, int dir, long nativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001335
Romain Guye4d01122010-06-16 18:44:05 -07001336 @Override
1337 public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001338 float x, float y, int dir, Paint paint) {
Romain Guy61c8c9c2010-08-09 20:48:09 -07001339 if ((start | end | end - start | text.length() - end) < 0) {
1340 throw new IndexOutOfBoundsException();
1341 }
1342
Romain Guya168d732011-03-18 16:50:13 -07001343 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001344 try {
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001345 int flags = dir == 0 ? 0 : 1;
Romain Guy61c8c9c2010-08-09 20:48:09 -07001346 if (text instanceof String || text instanceof SpannedString ||
1347 text instanceof SpannableString) {
1348 nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001349 contextEnd, x, y, flags, paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001350 } else if (text instanceof GraphicsOperations) {
1351 ((GraphicsOperations) text).drawTextRun(this, start, end,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001352 contextStart, contextEnd, x, y, flags, paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001353 } else {
1354 int contextLen = contextEnd - contextStart;
1355 int len = end - start;
1356 char[] buf = TemporaryBuffer.obtain(contextLen);
1357 TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
1358 nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
Fabrice Di Meglioda12f382013-03-15 11:26:56 -07001359 x, y, flags, paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001360 TemporaryBuffer.recycle(buf);
1361 }
1362 } finally {
Romain Guya168d732011-03-18 16:50:13 -07001363 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001364 }
Romain Guye4d01122010-06-16 18:44:05 -07001365 }
1366
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001367 private static native void nDrawTextRun(long renderer, String text, int start, int end,
1368 int contextStart, int contextEnd, float x, float y, int flags, long nativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -07001369
Romain Guye4d01122010-06-16 18:44:05 -07001370 @Override
1371 public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
1372 float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
1373 int indexOffset, int indexCount, Paint paint) {
Romain Guy6926c722010-07-12 20:20:03 -07001374 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -07001375 }
Romain Guyd27977d2010-07-14 19:18:51 -07001376
Romain Guya168d732011-03-18 16:50:13 -07001377 private int setupModifiers(Bitmap b, Paint paint) {
Romain Guy445c83c2012-02-16 16:43:07 -08001378 if (b.getConfig() != Bitmap.Config.ALPHA_8) {
1379 final ColorFilter filter = paint.getColorFilter();
1380 if (filter != null) {
1381 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
1382 return MODIFIER_COLOR_FILTER;
1383 }
1384
1385 return MODIFIER_NONE;
1386 } else {
Romain Guya168d732011-03-18 16:50:13 -07001387 return setupModifiers(paint);
1388 }
Romain Guya168d732011-03-18 16:50:13 -07001389 }
1390
1391 private int setupModifiers(Paint paint) {
1392 int modifiers = MODIFIER_NONE;
Romain Guydb1938e2010-08-02 18:50:22 -07001393
Romain Guy1e45aae2010-08-13 19:39:53 -07001394 if (paint.hasShadow) {
1395 nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
1396 paint.shadowColor);
Romain Guya168d732011-03-18 16:50:13 -07001397 modifiers |= MODIFIER_SHADOW;
Romain Guy1e45aae2010-08-13 19:39:53 -07001398 }
1399
Romain Guyd27977d2010-07-14 19:18:51 -07001400 final Shader shader = paint.getShader();
1401 if (shader != null) {
Romain Guy06f96e22010-07-30 19:18:16 -07001402 nSetupShader(mRenderer, shader.native_shader);
Romain Guya168d732011-03-18 16:50:13 -07001403 modifiers |= MODIFIER_SHADER;
Romain Guydb1938e2010-08-02 18:50:22 -07001404 }
1405
1406 final ColorFilter filter = paint.getColorFilter();
1407 if (filter != null) {
1408 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
Romain Guya168d732011-03-18 16:50:13 -07001409 modifiers |= MODIFIER_COLOR_FILTER;
Romain Guydb1938e2010-08-02 18:50:22 -07001410 }
1411
Romain Guya168d732011-03-18 16:50:13 -07001412 return modifiers;
Romain Guydb1938e2010-08-02 18:50:22 -07001413 }
Romain Guy1e45aae2010-08-13 19:39:53 -07001414
Romain Guy765dcf32012-02-27 13:28:22 -08001415 private int setupModifiers(Paint paint, int flags) {
1416 int modifiers = MODIFIER_NONE;
1417
1418 if (paint.hasShadow && (flags & MODIFIER_SHADOW) != 0) {
1419 nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
1420 paint.shadowColor);
1421 modifiers |= MODIFIER_SHADOW;
1422 }
1423
1424 final Shader shader = paint.getShader();
1425 if (shader != null && (flags & MODIFIER_SHADER) != 0) {
1426 nSetupShader(mRenderer, shader.native_shader);
1427 modifiers |= MODIFIER_SHADER;
1428 }
1429
1430 final ColorFilter filter = paint.getColorFilter();
1431 if (filter != null && (flags & MODIFIER_COLOR_FILTER) != 0) {
1432 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
1433 modifiers |= MODIFIER_COLOR_FILTER;
1434 }
1435
1436 return modifiers;
1437 }
1438
Romain Guya168d732011-03-18 16:50:13 -07001439 private int setupColorFilter(Paint paint) {
Romain Guydb1938e2010-08-02 18:50:22 -07001440 final ColorFilter filter = paint.getColorFilter();
1441 if (filter != null) {
1442 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
Romain Guya168d732011-03-18 16:50:13 -07001443 return MODIFIER_COLOR_FILTER;
Romain Guyd27977d2010-07-14 19:18:51 -07001444 }
Romain Guy56215272011-03-23 16:55:38 -07001445 return MODIFIER_NONE;
Romain Guyd27977d2010-07-14 19:18:51 -07001446 }
Romain Guya168d732011-03-18 16:50:13 -07001447
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001448 private static native void nSetupShader(long renderer, long shader);
1449 private static native void nSetupColorFilter(long renderer, long colorFilter);
1450 private static native void nSetupShadow(long renderer, float radius,
Romain Guy7d7b5492011-01-24 16:33:45 -08001451 float dx, float dy, int color);
Romain Guy1e45aae2010-08-13 19:39:53 -07001452
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001453 private static native void nResetModifiers(long renderer, int modifiers);
Romain Guye4d01122010-06-16 18:44:05 -07001454}