blob: 2b79a76bde45a8c1a3376357052eef43f22a575e [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;
24import android.graphics.Paint;
25import android.graphics.Path;
26import android.graphics.Picture;
27import android.graphics.PorterDuff;
28import android.graphics.Rect;
29import android.graphics.RectF;
30import android.graphics.Region;
Romain Guyd27977d2010-07-14 19:18:51 -070031import android.graphics.Shader;
Romain Guya1db5742010-07-20 13:09:13 -070032import android.graphics.TemporaryBuffer;
33import android.text.GraphicsOperations;
34import android.text.SpannableString;
35import android.text.SpannedString;
36import android.text.TextUtils;
Romain Guye4d01122010-06-16 18:44:05 -070037
Romain Guye4d01122010-06-16 18:44:05 -070038/**
39 * An implementation of Canvas on top of OpenGL ES 2.0.
40 */
Romain Guyb051e892010-09-28 19:09:36 -070041class GLES20Canvas extends HardwareCanvas {
Romain Guya168d732011-03-18 16:50:13 -070042 // Must match modifiers used in the JNI layer
43 private static final int MODIFIER_NONE = 0;
44 private static final int MODIFIER_SHADOW = 1;
45 private static final int MODIFIER_SHADER = 2;
46 private static final int MODIFIER_COLOR_FILTER = 4;
47
Romain Guye4d01122010-06-16 18:44:05 -070048 private final boolean mOpaque;
Romain Guyfb8b7632010-08-23 21:05:08 -070049 private int mRenderer;
Patrick Dubroyf890fab2010-12-19 16:47:17 -080050
51 // The native renderer will be destroyed when this object dies.
52 // DO NOT overwrite this reference once it is set.
53 private CanvasFinalizer mFinalizer;
54
Romain Guye4d01122010-06-16 18:44:05 -070055 private int mWidth;
56 private int mHeight;
Romain Guyce0537b2010-06-29 21:05:21 -070057
58 private final float[] mPoint = new float[2];
59 private final float[] mLine = new float[4];
Romain Guy6926c722010-07-12 20:20:03 -070060
61 private final Rect mClipBounds = new Rect();
62
63 private DrawFilter mFilter;
Romain Guyda8532c2010-08-31 11:50:35 -070064
Romain Guy16393512010-08-08 00:14:31 -070065 ///////////////////////////////////////////////////////////////////////////
66 // JNI
67 ///////////////////////////////////////////////////////////////////////////
68
69 private static native boolean nIsAvailable();
70 private static boolean sIsAvailable = nIsAvailable();
71
72 static boolean isAvailable() {
73 return sIsAvailable;
74 }
Romain Guye4d01122010-06-16 18:44:05 -070075
76 ///////////////////////////////////////////////////////////////////////////
77 // Constructors
78 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070079
Romain Guy6c319ca2011-01-11 14:29:25 -080080 /**
81 * Creates a canvas to render directly on screen.
82 */
Romain Guyb051e892010-09-28 19:09:36 -070083 GLES20Canvas(boolean translucent) {
84 this(false, translucent);
85 }
Romain Guy6c319ca2011-01-11 14:29:25 -080086
87 /**
88 * Creates a canvas to render into an FBO.
89 */
Romain Guyada830f2011-01-13 12:13:20 -080090 GLES20Canvas(int layer, boolean translucent) {
Romain Guy6c319ca2011-01-11 14:29:25 -080091 mOpaque = !translucent;
Romain Guyada830f2011-01-13 12:13:20 -080092 mRenderer = nCreateLayerRenderer(layer);
Romain Guy6c319ca2011-01-11 14:29:25 -080093 setupFinalizer();
94 }
Romain Guye4d01122010-06-16 18:44:05 -070095
Patrick Dubroyf890fab2010-12-19 16:47:17 -080096 protected GLES20Canvas(boolean record, boolean translucent) {
Romain Guye4d01122010-06-16 18:44:05 -070097 mOpaque = !translucent;
98
Chet Haase9e90a992011-01-04 16:23:21 -080099 setupRenderer(record);
100 }
101
102 protected void setupRenderer(boolean record) {
Romain Guyb051e892010-09-28 19:09:36 -0700103 if (record) {
Chet Haase5977baa2011-01-05 18:01:22 -0800104 mRenderer = nGetDisplayListRenderer(mRenderer);
Romain Guyb051e892010-09-28 19:09:36 -0700105 } else {
106 mRenderer = nCreateRenderer();
107 }
Romain Guy6c319ca2011-01-11 14:29:25 -0800108
109 setupFinalizer();
110 }
111
112 private void setupFinalizer() {
Romain Guyfb8b7632010-08-23 21:05:08 -0700113 if (mRenderer == 0) {
114 throw new IllegalStateException("Could not create GLES20Canvas renderer");
Chet Haase5c13d892010-10-08 08:37:55 -0700115 } else {
Chet Haase5977baa2011-01-05 18:01:22 -0800116 mFinalizer = CanvasFinalizer.getFinalizer(mFinalizer, mRenderer);
Romain Guyfb8b7632010-08-23 21:05:08 -0700117 }
Romain Guye4d01122010-06-16 18:44:05 -0700118 }
Romain Guye4d01122010-06-16 18:44:05 -0700119
Romain Guy6c319ca2011-01-11 14:29:25 -0800120 private static native int nCreateRenderer();
Romain Guyada830f2011-01-13 12:13:20 -0800121 private static native int nCreateLayerRenderer(int layer);
Chet Haase5977baa2011-01-05 18:01:22 -0800122 private static native int nGetDisplayListRenderer(int renderer);
Chet Haase5c13d892010-10-08 08:37:55 -0700123 private static native void nDestroyRenderer(int renderer);
124
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800125 private static class CanvasFinalizer {
Chet Haase9e90a992011-01-04 16:23:21 -0800126 int mRenderer;
Chet Haase5c13d892010-10-08 08:37:55 -0700127
Chet Haase5977baa2011-01-05 18:01:22 -0800128 // Factory method returns new instance if old one is null, or old instance
129 // otherwise, destroying native renderer along the way as necessary
130 static CanvasFinalizer getFinalizer(CanvasFinalizer oldFinalizer, int renderer) {
131 if (oldFinalizer == null) {
132 return new CanvasFinalizer(renderer);
133 }
134 oldFinalizer.replaceNativeObject(renderer);
135 return oldFinalizer;
136 }
137
138 private CanvasFinalizer(int renderer) {
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800139 mRenderer = renderer;
Chet Haase5c13d892010-10-08 08:37:55 -0700140 }
141
Chet Haase5977baa2011-01-05 18:01:22 -0800142 private void replaceNativeObject(int newRenderer) {
143 if (mRenderer != 0 && newRenderer != mRenderer) {
Chet Haase9e90a992011-01-04 16:23:21 -0800144 nDestroyRenderer(mRenderer);
145 }
146 mRenderer = newRenderer;
147 }
148
Chet Haase5c13d892010-10-08 08:37:55 -0700149 @Override
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800150 protected void finalize() throws Throwable {
Romain Guy171c5922011-01-06 10:04:23 -0800151 try {
152 replaceNativeObject(0);
153 } finally {
154 super.finalize();
155 }
Romain Guye4d01122010-06-16 18:44:05 -0700156 }
157 }
Romain Guyce0537b2010-06-29 21:05:21 -0700158
Romain Guye4d01122010-06-16 18:44:05 -0700159 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800160 // Hardware layers
161 ///////////////////////////////////////////////////////////////////////////
162
Romain Guyaa6c24c2011-04-28 18:40:04 -0700163 static native int nCreateTextureLayer(int[] layerInfo);
Romain Guyada830f2011-01-13 12:13:20 -0800164 static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
165 static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
Romain Guy8f0095c2011-05-02 17:24:22 -0700166 static native void nUpdateTextureLayer(int layerId, int width, int height, int surface);
Romain Guyada830f2011-01-13 12:13:20 -0800167 static native void nDestroyLayer(int layerId);
168 static native void nDestroyLayerDeferred(int layerId);
Romain Guy57066eb2011-01-12 12:53:32 -0800169
Romain Guy6c319ca2011-01-11 14:29:25 -0800170 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700171 // Canvas management
172 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700173
174 @Override
175 public boolean isOpaque() {
176 return mOpaque;
177 }
178
179 @Override
180 public int getWidth() {
181 return mWidth;
182 }
183
184 @Override
185 public int getHeight() {
186 return mHeight;
187 }
188
189 ///////////////////////////////////////////////////////////////////////////
190 // Setup
191 ///////////////////////////////////////////////////////////////////////////
192
193 @Override
194 public void setViewport(int width, int height) {
195 mWidth = width;
196 mHeight = height;
197
198 nSetViewport(mRenderer, width, height);
199 }
200
Romain Guy7d7b5492011-01-24 16:33:45 -0800201 private static native void nSetViewport(int renderer, int width, int height);
Romain Guye4d01122010-06-16 18:44:05 -0700202
Romain Guy7d7b5492011-01-24 16:33:45 -0800203 /**
204 * @hide
205 */
206 public static boolean preserveBackBuffer() {
207 return nPreserveBackBuffer();
Romain Guye4d01122010-06-16 18:44:05 -0700208 }
Romain Guyb025b9c2010-09-16 14:16:48 -0700209
Romain Guy7d7b5492011-01-24 16:33:45 -0800210 private static native boolean nPreserveBackBuffer();
211
212 @Override
213 void onPreDraw(Rect dirty) {
214 if (dirty != null) {
215 nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, mOpaque);
216 } else {
217 nPrepare(mRenderer, mOpaque);
218 }
219 }
220
221 private static native void nPrepare(int renderer, boolean opaque);
222 private static native void nPrepareDirty(int renderer, int left, int top, int right, int bottom,
223 boolean opaque);
Romain Guye4d01122010-06-16 18:44:05 -0700224
Romain Guyb051e892010-09-28 19:09:36 -0700225 @Override
Romain Guyb025b9c2010-09-16 14:16:48 -0700226 void onPostDraw() {
227 nFinish(mRenderer);
228 }
229
Romain Guy7d7b5492011-01-24 16:33:45 -0800230 private static native void nFinish(int renderer);
Romain Guyb025b9c2010-09-16 14:16:48 -0700231
Romain Guyda8532c2010-08-31 11:50:35 -0700232 @Override
Chet Haasedaf98e92011-01-10 14:10:36 -0800233 public boolean callDrawGLFunction(int drawGLFunction) {
234 return nCallDrawGLFunction(mRenderer, drawGLFunction);
235 }
236
Romain Guy7d7b5492011-01-24 16:33:45 -0800237 private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
Chet Haasedaf98e92011-01-10 14:10:36 -0800238
Romain Guyb051e892010-09-28 19:09:36 -0700239 ///////////////////////////////////////////////////////////////////////////
240 // Display list
241 ///////////////////////////////////////////////////////////////////////////
242
243 int getDisplayList() {
Chet Haase5977baa2011-01-05 18:01:22 -0800244 return nGetDisplayList(mRenderer);
Romain Guyb051e892010-09-28 19:09:36 -0700245 }
246
Romain Guy7d7b5492011-01-24 16:33:45 -0800247 private static native int nGetDisplayList(int renderer);
Romain Guyb051e892010-09-28 19:09:36 -0700248
Chet Haase5c13d892010-10-08 08:37:55 -0700249 static void destroyDisplayList(int displayList) {
Romain Guyb051e892010-09-28 19:09:36 -0700250 nDestroyDisplayList(displayList);
251 }
252
Chet Haase5c13d892010-10-08 08:37:55 -0700253 private static native void nDestroyDisplayList(int displayList);
Romain Guyb051e892010-09-28 19:09:36 -0700254
255 @Override
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700256 public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
Romain Guycabfcc12011-03-07 18:06:46 -0800257 return nDrawDisplayList(mRenderer,
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700258 ((GLES20DisplayList) displayList).mNativeDisplayList, width, height, dirty);
Romain Guyb051e892010-09-28 19:09:36 -0700259 }
260
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700261 private static native boolean nDrawDisplayList(int renderer, int displayList,
262 int width, int height, Rect dirty);
Romain Guyda8532c2010-08-31 11:50:35 -0700263
Chet Haaseed30fd82011-04-22 16:18:45 -0700264 @Override
265 void outputDisplayList(DisplayList displayList) {
266 nOutputDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
267 }
268
269 private static native void nOutputDisplayList(int renderer, int displayList);
270
Romain Guye4d01122010-06-16 18:44:05 -0700271 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800272 // Hardware layer
273 ///////////////////////////////////////////////////////////////////////////
274
Romain Guyada830f2011-01-13 12:13:20 -0800275 void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
Romain Guy6c319ca2011-01-11 14:29:25 -0800276 final GLES20Layer glLayer = (GLES20Layer) layer;
Romain Guya168d732011-03-18 16:50:13 -0700277 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy6c319ca2011-01-11 14:29:25 -0800278 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guyada830f2011-01-13 12:13:20 -0800279 nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700280 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
Romain Guy6c319ca2011-01-11 14:29:25 -0800281 }
282
Romain Guy7d7b5492011-01-24 16:33:45 -0800283 private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
Romain Guyaa6c24c2011-04-28 18:40:04 -0700284
Romain Guy6c319ca2011-01-11 14:29:25 -0800285 void interrupt() {
286 nInterrupt(mRenderer);
287 }
288
289 void resume() {
290 nResume(mRenderer);
291 }
292
Romain Guy7d7b5492011-01-24 16:33:45 -0800293 private static native void nInterrupt(int renderer);
294 private static native void nResume(int renderer);
Romain Guy6c319ca2011-01-11 14:29:25 -0800295
296 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700297 // Clipping
298 ///////////////////////////////////////////////////////////////////////////
299
300 @Override
301 public boolean clipPath(Path path) {
302 throw new UnsupportedOperationException();
303 }
304
305 @Override
306 public boolean clipPath(Path path, Region.Op op) {
307 throw new UnsupportedOperationException();
308 }
309
310 @Override
311 public boolean clipRect(float left, float top, float right, float bottom) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700312 return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700313 }
Romain Guybb9524b2010-06-22 18:56:38 -0700314
Romain Guy7d7b5492011-01-24 16:33:45 -0800315 private static native boolean nClipRect(int renderer, float left, float top,
Romain Guy079ba2c2010-07-16 14:12:24 -0700316 float right, float bottom, int op);
Romain Guye4d01122010-06-16 18:44:05 -0700317
318 @Override
319 public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700320 return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700321 }
322
323 @Override
324 public boolean clipRect(int left, int top, int right, int bottom) {
Chet Haasedaf98e92011-01-10 14:10:36 -0800325 return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700326 }
Romain Guybb9524b2010-06-22 18:56:38 -0700327
Romain Guy7d7b5492011-01-24 16:33:45 -0800328 private static native boolean nClipRect(int renderer, int left, int top, int right, int bottom,
329 int op);
Romain Guye4d01122010-06-16 18:44:05 -0700330
331 @Override
332 public boolean clipRect(Rect rect) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700333 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
334 Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700335 }
336
337 @Override
338 public boolean clipRect(Rect rect, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700339 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700340 }
341
342 @Override
343 public boolean clipRect(RectF rect) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700344 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
345 Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700346 }
347
348 @Override
349 public boolean clipRect(RectF rect, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700350 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700351 }
352
353 @Override
354 public boolean clipRegion(Region region) {
355 throw new UnsupportedOperationException();
356 }
357
358 @Override
359 public boolean clipRegion(Region region, Region.Op op) {
360 throw new UnsupportedOperationException();
361 }
362
363 @Override
364 public boolean getClipBounds(Rect bounds) {
Romain Guy9d5316e2010-06-24 19:30:36 -0700365 return nGetClipBounds(mRenderer, bounds);
Romain Guye4d01122010-06-16 18:44:05 -0700366 }
367
Romain Guy7d7b5492011-01-24 16:33:45 -0800368 private static native boolean nGetClipBounds(int renderer, Rect bounds);
Romain Guy9d5316e2010-06-24 19:30:36 -0700369
Romain Guye4d01122010-06-16 18:44:05 -0700370 @Override
371 public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
Romain Guyc7d53492010-06-25 13:41:57 -0700372 return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700373 }
Romain Guyc7d53492010-06-25 13:41:57 -0700374
Romain Guy7d7b5492011-01-24 16:33:45 -0800375 private static native boolean nQuickReject(int renderer, float left, float top,
Romain Guyc7d53492010-06-25 13:41:57 -0700376 float right, float bottom, int edge);
Romain Guye4d01122010-06-16 18:44:05 -0700377
378 @Override
379 public boolean quickReject(Path path, EdgeType type) {
Romain Guybb9524b2010-06-22 18:56:38 -0700380 throw new UnsupportedOperationException();
Romain Guye4d01122010-06-16 18:44:05 -0700381 }
382
383 @Override
384 public boolean quickReject(RectF rect, EdgeType type) {
Romain Guybb9524b2010-06-22 18:56:38 -0700385 return quickReject(rect.left, rect.top, rect.right, rect.bottom, type);
Romain Guye4d01122010-06-16 18:44:05 -0700386 }
387
388 ///////////////////////////////////////////////////////////////////////////
389 // Transformations
390 ///////////////////////////////////////////////////////////////////////////
391
392 @Override
393 public void translate(float dx, float dy) {
Romain Guy807daf72011-01-18 11:19:19 -0800394 if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy);
Romain Guye4d01122010-06-16 18:44:05 -0700395 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700396
Romain Guy7d7b5492011-01-24 16:33:45 -0800397 private static native void nTranslate(int renderer, float dx, float dy);
Romain Guye4d01122010-06-16 18:44:05 -0700398
399 @Override
400 public void skew(float sx, float sy) {
Romain Guy807daf72011-01-18 11:19:19 -0800401 nSkew(mRenderer, sx, sy);
Romain Guye4d01122010-06-16 18:44:05 -0700402 }
403
Romain Guy7d7b5492011-01-24 16:33:45 -0800404 private static native void nSkew(int renderer, float sx, float sy);
Romain Guy807daf72011-01-18 11:19:19 -0800405
Romain Guye4d01122010-06-16 18:44:05 -0700406 @Override
407 public void rotate(float degrees) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700408 nRotate(mRenderer, degrees);
Romain Guye4d01122010-06-16 18:44:05 -0700409 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700410
Romain Guy7d7b5492011-01-24 16:33:45 -0800411 private static native void nRotate(int renderer, float degrees);
Romain Guye4d01122010-06-16 18:44:05 -0700412
413 @Override
414 public void scale(float sx, float sy) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700415 nScale(mRenderer, sx, sy);
Romain Guye4d01122010-06-16 18:44:05 -0700416 }
Romain Guye4d01122010-06-16 18:44:05 -0700417
Romain Guy7d7b5492011-01-24 16:33:45 -0800418 private static native void nScale(int renderer, float sx, float sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700419
Romain Guye4d01122010-06-16 18:44:05 -0700420 @Override
421 public void setMatrix(Matrix matrix) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700422 nSetMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700423 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700424
Romain Guy7d7b5492011-01-24 16:33:45 -0800425 private static native void nSetMatrix(int renderer, int matrix);
Romain Guye4d01122010-06-16 18:44:05 -0700426
427 @Override
Romain Guy41030da2010-10-13 13:40:37 -0700428 public int getNativeMatrix() {
429 return nGetMatrix(mRenderer);
430 }
431
Romain Guy7d7b5492011-01-24 16:33:45 -0800432 private static native int nGetMatrix(int renderer);
Romain Guy41030da2010-10-13 13:40:37 -0700433
434 @Override
Romain Guyf6a11b82010-06-23 17:47:49 -0700435 public void getMatrix(Matrix matrix) {
436 nGetMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700437 }
Romain Guyf6a11b82010-06-23 17:47:49 -0700438
Romain Guy7d7b5492011-01-24 16:33:45 -0800439 private static native void nGetMatrix(int renderer, int matrix);
Romain Guye4d01122010-06-16 18:44:05 -0700440
441 @Override
442 public void concat(Matrix matrix) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700443 nConcatMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700444 }
445
Romain Guy7d7b5492011-01-24 16:33:45 -0800446 private static native void nConcatMatrix(int renderer, int matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700447
Romain Guye4d01122010-06-16 18:44:05 -0700448 ///////////////////////////////////////////////////////////////////////////
449 // State management
450 ///////////////////////////////////////////////////////////////////////////
451
452 @Override
453 public int save() {
Romain Guy8aef54f2010-09-01 15:13:49 -0700454 return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
Romain Guye4d01122010-06-16 18:44:05 -0700455 }
Romain Guybb9524b2010-06-22 18:56:38 -0700456
Romain Guye4d01122010-06-16 18:44:05 -0700457 @Override
458 public int save(int saveFlags) {
Romain Guybb9524b2010-06-22 18:56:38 -0700459 return nSave(mRenderer, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700460 }
461
Romain Guy7d7b5492011-01-24 16:33:45 -0800462 private static native int nSave(int renderer, int flags);
Romain Guybb9524b2010-06-22 18:56:38 -0700463
Romain Guye4d01122010-06-16 18:44:05 -0700464 @Override
465 public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
Romain Guybd6b79b2010-06-26 00:13:53 -0700466 return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700467 }
468
469 @Override
470 public int saveLayer(float left, float top, float right, float bottom, Paint paint,
471 int saveFlags) {
Romain Guy01d58e42011-01-19 21:54:02 -0800472 if (left < right && top < bottom) {
Romain Guya168d732011-03-18 16:50:13 -0700473 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy01d58e42011-01-19 21:54:02 -0800474 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
475 int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
Romain Guya168d732011-03-18 16:50:13 -0700476 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
Romain Guy01d58e42011-01-19 21:54:02 -0800477 return count;
478 }
479 return save(saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700480 }
481
Romain Guy7d7b5492011-01-24 16:33:45 -0800482 private static native int nSaveLayer(int renderer, float left, float top,
483 float right, float bottom, int paint, int saveFlags);
Romain Guybd6b79b2010-06-26 00:13:53 -0700484
Romain Guye4d01122010-06-16 18:44:05 -0700485 @Override
486 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
Romain Guybd6b79b2010-06-26 00:13:53 -0700487 return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
488 alpha, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700489 }
490
491 @Override
492 public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
493 int saveFlags) {
Romain Guy01d58e42011-01-19 21:54:02 -0800494 if (left < right && top < bottom) {
495 return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
496 }
497 return save(saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700498 }
499
Romain Guy7d7b5492011-01-24 16:33:45 -0800500 private static native int nSaveLayerAlpha(int renderer, float left, float top, float right,
Romain Guybd6b79b2010-06-26 00:13:53 -0700501 float bottom, int alpha, int saveFlags);
502
Romain Guye4d01122010-06-16 18:44:05 -0700503 @Override
504 public void restore() {
Romain Guybb9524b2010-06-22 18:56:38 -0700505 nRestore(mRenderer);
Romain Guye4d01122010-06-16 18:44:05 -0700506 }
Romain Guybb9524b2010-06-22 18:56:38 -0700507
Romain Guy7d7b5492011-01-24 16:33:45 -0800508 private static native void nRestore(int renderer);
Romain Guye4d01122010-06-16 18:44:05 -0700509
510 @Override
511 public void restoreToCount(int saveCount) {
Romain Guybb9524b2010-06-22 18:56:38 -0700512 nRestoreToCount(mRenderer, saveCount);
Romain Guye4d01122010-06-16 18:44:05 -0700513 }
514
Romain Guy7d7b5492011-01-24 16:33:45 -0800515 private static native void nRestoreToCount(int renderer, int saveCount);
Romain Guybb9524b2010-06-22 18:56:38 -0700516
Romain Guye4d01122010-06-16 18:44:05 -0700517 @Override
518 public int getSaveCount() {
Romain Guybb9524b2010-06-22 18:56:38 -0700519 return nGetSaveCount(mRenderer);
Romain Guye4d01122010-06-16 18:44:05 -0700520 }
Romain Guybb9524b2010-06-22 18:56:38 -0700521
Romain Guy7d7b5492011-01-24 16:33:45 -0800522 private static native int nGetSaveCount(int renderer);
Romain Guye4d01122010-06-16 18:44:05 -0700523
524 ///////////////////////////////////////////////////////////////////////////
525 // Filtering
526 ///////////////////////////////////////////////////////////////////////////
527
528 @Override
529 public void setDrawFilter(DrawFilter filter) {
Romain Guy6926c722010-07-12 20:20:03 -0700530 mFilter = filter;
Romain Guye4d01122010-06-16 18:44:05 -0700531 }
532
533 @Override
534 public DrawFilter getDrawFilter() {
Romain Guy6926c722010-07-12 20:20:03 -0700535 return mFilter;
Romain Guye4d01122010-06-16 18:44:05 -0700536 }
537
538 ///////////////////////////////////////////////////////////////////////////
539 // Drawing
540 ///////////////////////////////////////////////////////////////////////////
541
542 @Override
543 public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
544 Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700545 int modifiers = setupModifiers(paint);
Romain Guy8b2f5262011-01-23 16:15:02 -0800546 nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle,
547 useCenter, paint.mNativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700548 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700549 }
550
Romain Guy7d7b5492011-01-24 16:33:45 -0800551 private static native void nDrawArc(int renderer, float left, float top,
552 float right, float bottom, float startAngle, float sweepAngle,
553 boolean useCenter, int paint);
Romain Guy8b2f5262011-01-23 16:15:02 -0800554
Romain Guye4d01122010-06-16 18:44:05 -0700555 @Override
556 public void drawARGB(int a, int r, int g, int b) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700557 drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
Romain Guye4d01122010-06-16 18:44:05 -0700558 }
559
560 @Override
Romain Guydeba7852010-07-07 17:54:48 -0700561 public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700562 // Shaders are ignored when drawing patches
Romain Guya168d732011-03-18 16:50:13 -0700563 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guydeba7852010-07-07 17:54:48 -0700564 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800565 nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks,
566 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700567 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
Romain Guydeba7852010-07-07 17:54:48 -0700568 }
569
Romain Guy7d7b5492011-01-24 16:33:45 -0800570 private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800571 float left, float top, float right, float bottom, int paint);
Romain Guydeba7852010-07-07 17:54:48 -0700572
573 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700574 public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700575 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700576 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guyce0537b2010-06-29 21:05:21 -0700577 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800578 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700579 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700580 }
581
Romain Guy7d7b5492011-01-24 16:33:45 -0800582 private static native void nDrawBitmap(
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800583 int renderer, int bitmap, byte[] buffer, float left, float top, int paint);
Romain Guydbd77cd2010-07-09 10:36:05 -0700584
Romain Guye4d01122010-06-16 18:44:05 -0700585 @Override
586 public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700587 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700588 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guyce0537b2010-06-29 21:05:21 -0700589 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800590 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
591 matrix.native_instance, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700592 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700593 }
594
Romain Guy7d7b5492011-01-24 16:33:45 -0800595 private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff,
596 int matrix, int paint);
Romain Guyf86ef572010-07-01 11:05:42 -0700597
Romain Guye4d01122010-06-16 18:44:05 -0700598 @Override
599 public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700600 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700601 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guyce0537b2010-06-29 21:05:21 -0700602 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guy694b5192010-07-21 21:33:20 -0700603
604 int left, top, right, bottom;
605 if (src == null) {
606 left = top = 0;
607 right = bitmap.getWidth();
608 bottom = bitmap.getHeight();
609 } else {
610 left = src.left;
611 right = src.right;
612 top = src.top;
613 bottom = src.bottom;
614 }
615
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800616 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
Romain Guy694b5192010-07-21 21:33:20 -0700617 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700618 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700619 }
620
621 @Override
622 public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700623 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700624 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guyce0537b2010-06-29 21:05:21 -0700625 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800626 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, src.left, src.top, src.right,
627 src.bottom, dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700628 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700629 }
630
Romain Guy7d7b5492011-01-24 16:33:45 -0800631 private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
Romain Guyce0537b2010-06-29 21:05:21 -0700632 float srcLeft, float srcTop, float srcRight, float srcBottom,
Romain Guydbd77cd2010-07-09 10:36:05 -0700633 float left, float top, float right, float bottom, int paint);
Romain Guyce0537b2010-06-29 21:05:21 -0700634
Romain Guye4d01122010-06-16 18:44:05 -0700635 @Override
636 public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
637 int width, int height, boolean hasAlpha, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700638 // Shaders are ignored when drawing bitmaps
Romain Guya168d732011-03-18 16:50:13 -0700639 int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
Romain Guy6926c722010-07-12 20:20:03 -0700640 final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
641 final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config);
642 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800643 nDrawBitmap(mRenderer, b.mNativeBitmap, b.mBuffer, x, y, nativePaint);
Romain Guy6926c722010-07-12 20:20:03 -0700644 b.recycle();
Romain Guya168d732011-03-18 16:50:13 -0700645 if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
Romain Guye4d01122010-06-16 18:44:05 -0700646 }
647
648 @Override
649 public void drawBitmap(int[] colors, int offset, int stride, int x, int y,
650 int width, int height, boolean hasAlpha, Paint paint) {
Romain Guyd27977d2010-07-14 19:18:51 -0700651 // Shaders are ignored when drawing bitmaps
Romain Guyce0537b2010-06-29 21:05:21 -0700652 drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700653 }
654
655 @Override
656 public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
657 int vertOffset, int[] colors, int colorOffset, Paint paint) {
Romain Guy5a7b4662011-01-20 19:09:30 -0800658 if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
659 throw new ArrayIndexOutOfBoundsException();
660 }
661
662 if (meshWidth == 0 || meshHeight == 0) {
663 return;
664 }
665
666 final int count = (meshWidth + 1) * (meshHeight + 1);
667 checkRange(verts.length, vertOffset, count * 2);
668
669 // TODO: Colors are ignored for now
670 colors = null;
671 colorOffset = 0;
672
Romain Guya168d732011-03-18 16:50:13 -0700673 int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
Romain Guy5a7b4662011-01-20 19:09:30 -0800674 final int nativePaint = paint == null ? 0 : paint.mNativePaint;
675 nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
676 verts, vertOffset, colors, colorOffset, nativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700677 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700678 }
679
Romain Guy7d7b5492011-01-24 16:33:45 -0800680 private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
Romain Guy5a7b4662011-01-20 19:09:30 -0800681 int meshWidth, int meshHeight, float[] verts, int vertOffset,
682 int[] colors, int colorOffset, int paint);
683
Romain Guye4d01122010-06-16 18:44:05 -0700684 @Override
685 public void drawCircle(float cx, float cy, float radius, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700686 int modifiers = setupModifiers(paint);
Romain Guy01d58e42011-01-19 21:54:02 -0800687 nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700688 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700689 }
690
Romain Guy7d7b5492011-01-24 16:33:45 -0800691 private static native void nDrawCircle(int renderer, float cx, float cy,
692 float radius, int paint);
Romain Guy01d58e42011-01-19 21:54:02 -0800693
Romain Guye4d01122010-06-16 18:44:05 -0700694 @Override
695 public void drawColor(int color) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700696 drawColor(color, PorterDuff.Mode.SRC_OVER);
Romain Guye4d01122010-06-16 18:44:05 -0700697 }
698
699 @Override
700 public void drawColor(int color, PorterDuff.Mode mode) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700701 nDrawColor(mRenderer, color, mode.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700702 }
Romain Guy85bf02f2010-06-22 13:11:24 -0700703
Romain Guy7d7b5492011-01-24 16:33:45 -0800704 private static native void nDrawColor(int renderer, int color, int mode);
Romain Guye4d01122010-06-16 18:44:05 -0700705
706 @Override
707 public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
Romain Guyce0537b2010-06-29 21:05:21 -0700708 mLine[0] = startX;
709 mLine[1] = startY;
710 mLine[2] = stopX;
711 mLine[3] = stopY;
Romain Guy759ea802010-09-16 20:49:46 -0700712 drawLines(mLine, 0, 4, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700713 }
714
715 @Override
716 public void drawLines(float[] pts, int offset, int count, Paint paint) {
Romain Guy759ea802010-09-16 20:49:46 -0700717 if ((offset | count) < 0 || offset + count > pts.length) {
718 throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
719 }
Romain Guya168d732011-03-18 16:50:13 -0700720 int modifiers = setupModifiers(paint);
Romain Guy759ea802010-09-16 20:49:46 -0700721 nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700722 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700723 }
724
Romain Guy7d7b5492011-01-24 16:33:45 -0800725 private static native void nDrawLines(int renderer, float[] points,
726 int offset, int count, int paint);
Romain Guy759ea802010-09-16 20:49:46 -0700727
Romain Guye4d01122010-06-16 18:44:05 -0700728 @Override
729 public void drawLines(float[] pts, Paint paint) {
Romain Guy759ea802010-09-16 20:49:46 -0700730 drawLines(pts, 0, pts.length, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700731 }
732
733 @Override
734 public void drawOval(RectF oval, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700735 int modifiers = setupModifiers(paint);
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800736 nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700737 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700738 }
739
Romain Guy7d7b5492011-01-24 16:33:45 -0800740 private static native void nDrawOval(int renderer, float left, float top,
741 float right, float bottom, int paint);
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800742
Romain Guye4d01122010-06-16 18:44:05 -0700743 @Override
744 public void drawPaint(Paint paint) {
Romain Guy6926c722010-07-12 20:20:03 -0700745 final Rect r = mClipBounds;
746 nGetClipBounds(mRenderer, r);
747 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700748 }
749
750 @Override
751 public void drawPath(Path path, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700752 int modifiers = setupModifiers(paint);
Romain Guya48a1a82010-08-10 14:59:15 -0700753 if (path.isSimplePath) {
754 if (path.rects != null) {
755 nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
756 }
757 } else {
758 nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
759 }
Romain Guya168d732011-03-18 16:50:13 -0700760 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700761 }
762
Romain Guy7d7b5492011-01-24 16:33:45 -0800763 private static native void nDrawPath(int renderer, int path, int paint);
764 private static native void nDrawRects(int renderer, int region, int paint);
Romain Guy7fbcc042010-08-04 15:40:07 -0700765
Romain Guye4d01122010-06-16 18:44:05 -0700766 @Override
767 public void drawPicture(Picture picture) {
768 throw new UnsupportedOperationException();
769 }
770
771 @Override
772 public void drawPicture(Picture picture, Rect dst) {
773 throw new UnsupportedOperationException();
774 }
775
776 @Override
777 public void drawPicture(Picture picture, RectF dst) {
778 throw new UnsupportedOperationException();
779 }
780
781 @Override
782 public void drawPoint(float x, float y, Paint paint) {
Romain Guyce0537b2010-06-29 21:05:21 -0700783 mPoint[0] = x;
784 mPoint[1] = y;
Romain Guyed6fcb02011-03-21 13:11:28 -0700785 drawPoints(mPoint, 0, 2, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700786 }
787
788 @Override
789 public void drawPoints(float[] pts, Paint paint) {
Romain Guyed6fcb02011-03-21 13:11:28 -0700790 drawPoints(pts, 0, pts.length, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700791 }
792
793 @Override
Romain Guyed6fcb02011-03-21 13:11:28 -0700794 public void drawPoints(float[] pts, int offset, int count, Paint paint) {
795 int modifiers = setupModifiers(paint);
796 nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
797 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
798 }
799
800 private static native void nDrawPoints(int renderer, float[] points,
801 int offset, int count, int paint);
802
803 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700804 public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800805 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -0700806 }
807
808 @Override
809 public void drawPosText(String text, float[] pos, Paint paint) {
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800810 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -0700811 }
812
813 @Override
814 public void drawRect(float left, float top, float right, float bottom, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700815 int modifiers = setupModifiers(paint);
Romain Guyc7d53492010-06-25 13:41:57 -0700816 nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700817 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700818 }
819
Romain Guy7d7b5492011-01-24 16:33:45 -0800820 private static native void nDrawRect(int renderer, float left, float top,
821 float right, float bottom, int paint);
Romain Guyc7d53492010-06-25 13:41:57 -0700822
Romain Guye4d01122010-06-16 18:44:05 -0700823 @Override
824 public void drawRect(Rect r, Paint paint) {
Romain Guyc7d53492010-06-25 13:41:57 -0700825 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700826 }
827
828 @Override
Romain Guyc7d53492010-06-25 13:41:57 -0700829 public void drawRect(RectF r, Paint paint) {
830 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700831 }
832
833 @Override
834 public void drawRGB(int r, int g, int b) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700835 drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
Romain Guye4d01122010-06-16 18:44:05 -0700836 }
837
838 @Override
839 public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700840 int modifiers = setupModifiers(paint);
Romain Guy01d58e42011-01-19 21:54:02 -0800841 nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
842 rx, ry, paint.mNativePaint);
Romain Guya168d732011-03-18 16:50:13 -0700843 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guye4d01122010-06-16 18:44:05 -0700844 }
845
Romain Guy7d7b5492011-01-24 16:33:45 -0800846 private static native void nDrawRoundRect(int renderer, float left, float top,
Romain Guy01d58e42011-01-19 21:54:02 -0800847 float right, float bottom, float rx, float y, int paint);
848
Romain Guye4d01122010-06-16 18:44:05 -0700849 @Override
850 public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
Romain Guya1db5742010-07-20 13:09:13 -0700851 if ((index | count | (index + count) | (text.length - index - count)) < 0) {
852 throw new IndexOutOfBoundsException();
853 }
Romain Guy61c8c9c2010-08-09 20:48:09 -0700854
Romain Guya168d732011-03-18 16:50:13 -0700855 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700856 try {
857 nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint);
858 } finally {
Romain Guya168d732011-03-18 16:50:13 -0700859 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700860 }
Romain Guye4d01122010-06-16 18:44:05 -0700861 }
Romain Guya1db5742010-07-20 13:09:13 -0700862
Romain Guy7d7b5492011-01-24 16:33:45 -0800863 private static native void nDrawText(int renderer, char[] text, int index, int count,
864 float x, float y, int bidiFlags, int paint);
Romain Guye4d01122010-06-16 18:44:05 -0700865
866 @Override
867 public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700868 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700869 try {
870 if (text instanceof String || text instanceof SpannedString ||
871 text instanceof SpannableString) {
872 nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
873 paint.mNativePaint);
874 } else if (text instanceof GraphicsOperations) {
875 ((GraphicsOperations) text).drawText(this, start, end, x, y,
876 paint);
877 } else {
878 char[] buf = TemporaryBuffer.obtain(end - start);
879 TextUtils.getChars(text, start, end, buf, 0);
Romain Guy7d7b5492011-01-24 16:33:45 -0800880 nDrawText(mRenderer, buf, 0, end - start, x, y,
881 paint.mBidiFlags, paint.mNativePaint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700882 TemporaryBuffer.recycle(buf);
883 }
884 } finally {
Romain Guya168d732011-03-18 16:50:13 -0700885 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guya1db5742010-07-20 13:09:13 -0700886 }
Romain Guye4d01122010-06-16 18:44:05 -0700887 }
888
889 @Override
890 public void drawText(String text, int start, int end, float x, float y, Paint paint) {
Romain Guya1db5742010-07-20 13:09:13 -0700891 if ((start | end | (end - start) | (text.length() - end)) < 0) {
892 throw new IndexOutOfBoundsException();
893 }
Romain Guy61c8c9c2010-08-09 20:48:09 -0700894
Romain Guya168d732011-03-18 16:50:13 -0700895 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700896 try {
897 nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint);
898 } finally {
Romain Guya168d732011-03-18 16:50:13 -0700899 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700900 }
Romain Guye4d01122010-06-16 18:44:05 -0700901 }
902
Romain Guy7d7b5492011-01-24 16:33:45 -0800903 private static native void nDrawText(int renderer, String text, int start, int end,
904 float x, float y, int bidiFlags, int paint);
Romain Guya1db5742010-07-20 13:09:13 -0700905
Romain Guye4d01122010-06-16 18:44:05 -0700906 @Override
907 public void drawText(String text, float x, float y, Paint paint) {
Romain Guya168d732011-03-18 16:50:13 -0700908 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700909 try {
910 nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags,
911 paint.mNativePaint);
912 } finally {
Romain Guya168d732011-03-18 16:50:13 -0700913 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700914 }
Romain Guye4d01122010-06-16 18:44:05 -0700915 }
916
917 @Override
918 public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
919 float vOffset, Paint paint) {
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800920 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -0700921 }
922
923 @Override
924 public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800925 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -0700926 }
927
928 @Override
929 public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
930 float x, float y, int dir, Paint paint) {
Romain Guy61c8c9c2010-08-09 20:48:09 -0700931 if ((index | count | text.length - index - count) < 0) {
932 throw new IndexOutOfBoundsException();
933 }
934 if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) {
935 throw new IllegalArgumentException("Unknown direction: " + dir);
936 }
937
Romain Guya168d732011-03-18 16:50:13 -0700938 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700939 try {
940 nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir,
941 paint.mNativePaint);
942 } finally {
Romain Guya168d732011-03-18 16:50:13 -0700943 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700944 }
Romain Guye4d01122010-06-16 18:44:05 -0700945 }
946
Romain Guy7d7b5492011-01-24 16:33:45 -0800947 private static native void nDrawTextRun(int renderer, char[] text, int index, int count,
Romain Guy61c8c9c2010-08-09 20:48:09 -0700948 int contextIndex, int contextCount, float x, float y, int dir, int nativePaint);
949
Romain Guye4d01122010-06-16 18:44:05 -0700950 @Override
951 public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
952 float x, float y, int dir, Paint paint) {
Romain Guy61c8c9c2010-08-09 20:48:09 -0700953 if ((start | end | end - start | text.length() - end) < 0) {
954 throw new IndexOutOfBoundsException();
955 }
956
Romain Guya168d732011-03-18 16:50:13 -0700957 int modifiers = setupModifiers(paint);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700958 try {
959 int flags = dir == 0 ? 0 : 1;
960 if (text instanceof String || text instanceof SpannedString ||
961 text instanceof SpannableString) {
962 nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
963 contextEnd, x, y, flags, paint.mNativePaint);
964 } else if (text instanceof GraphicsOperations) {
965 ((GraphicsOperations) text).drawTextRun(this, start, end,
966 contextStart, contextEnd, x, y, flags, paint);
967 } else {
968 int contextLen = contextEnd - contextStart;
969 int len = end - start;
970 char[] buf = TemporaryBuffer.obtain(contextLen);
971 TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
972 nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
973 x, y, flags, paint.mNativePaint);
974 TemporaryBuffer.recycle(buf);
975 }
976 } finally {
Romain Guya168d732011-03-18 16:50:13 -0700977 if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700978 }
Romain Guye4d01122010-06-16 18:44:05 -0700979 }
980
Romain Guy7d7b5492011-01-24 16:33:45 -0800981 private static native void nDrawTextRun(int renderer, String text, int start, int end,
Romain Guy61c8c9c2010-08-09 20:48:09 -0700982 int contextStart, int contextEnd, float x, float y, int flags, int nativePaint);
983
Romain Guye4d01122010-06-16 18:44:05 -0700984 @Override
985 public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
986 float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
987 int indexOffset, int indexCount, Paint paint) {
Romain Guy6926c722010-07-12 20:20:03 -0700988 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -0700989 }
Romain Guyd27977d2010-07-14 19:18:51 -0700990
Romain Guya168d732011-03-18 16:50:13 -0700991 private int setupModifiers(Bitmap b, Paint paint) {
992 if (b.getConfig() == Bitmap.Config.ALPHA_8) {
993 return setupModifiers(paint);
994 }
Romain Guy56215272011-03-23 16:55:38 -0700995
996 final ColorFilter filter = paint.getColorFilter();
997 if (filter != null) {
998 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
999 return MODIFIER_COLOR_FILTER;
1000 }
1001
Romain Guya168d732011-03-18 16:50:13 -07001002 return MODIFIER_NONE;
1003 }
1004
1005 private int setupModifiers(Paint paint) {
1006 int modifiers = MODIFIER_NONE;
Romain Guydb1938e2010-08-02 18:50:22 -07001007
Romain Guy1e45aae2010-08-13 19:39:53 -07001008 if (paint.hasShadow) {
1009 nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
1010 paint.shadowColor);
Romain Guya168d732011-03-18 16:50:13 -07001011 modifiers |= MODIFIER_SHADOW;
Romain Guy1e45aae2010-08-13 19:39:53 -07001012 }
1013
Romain Guyd27977d2010-07-14 19:18:51 -07001014 final Shader shader = paint.getShader();
1015 if (shader != null) {
Romain Guy06f96e22010-07-30 19:18:16 -07001016 nSetupShader(mRenderer, shader.native_shader);
Romain Guya168d732011-03-18 16:50:13 -07001017 modifiers |= MODIFIER_SHADER;
Romain Guydb1938e2010-08-02 18:50:22 -07001018 }
1019
1020 final ColorFilter filter = paint.getColorFilter();
1021 if (filter != null) {
1022 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
Romain Guya168d732011-03-18 16:50:13 -07001023 modifiers |= MODIFIER_COLOR_FILTER;
Romain Guydb1938e2010-08-02 18:50:22 -07001024 }
1025
Romain Guya168d732011-03-18 16:50:13 -07001026 return modifiers;
Romain Guydb1938e2010-08-02 18:50:22 -07001027 }
Romain Guy1e45aae2010-08-13 19:39:53 -07001028
Romain Guya168d732011-03-18 16:50:13 -07001029 private int setupColorFilter(Paint paint) {
Romain Guydb1938e2010-08-02 18:50:22 -07001030 final ColorFilter filter = paint.getColorFilter();
1031 if (filter != null) {
1032 nSetupColorFilter(mRenderer, filter.nativeColorFilter);
Romain Guya168d732011-03-18 16:50:13 -07001033 return MODIFIER_COLOR_FILTER;
Romain Guyd27977d2010-07-14 19:18:51 -07001034 }
Romain Guy56215272011-03-23 16:55:38 -07001035 return MODIFIER_NONE;
Romain Guyd27977d2010-07-14 19:18:51 -07001036 }
Romain Guya168d732011-03-18 16:50:13 -07001037
Romain Guy7d7b5492011-01-24 16:33:45 -08001038 private static native void nSetupShader(int renderer, int shader);
1039 private static native void nSetupColorFilter(int renderer, int colorFilter);
1040 private static native void nSetupShadow(int renderer, float radius,
1041 float dx, float dy, int color);
Romain Guy1e45aae2010-08-13 19:39:53 -07001042
Romain Guya168d732011-03-18 16:50:13 -07001043 private static native void nResetModifiers(int renderer, int modifiers);
Romain Guye4d01122010-06-16 18:44:05 -07001044}