blob: ceea9f8f02341048b188a7be5f748476216e61d8 [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;
John Reck52244ff2014-05-01 21:27:37 -070021import android.graphics.CanvasProperty;
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 Guya1db5742010-07-20 13:09:13 -070034import android.graphics.TemporaryBuffer;
35import android.text.GraphicsOperations;
36import android.text.SpannableString;
37import android.text.SpannedString;
38import android.text.TextUtils;
Romain Guye4d01122010-06-16 18:44:05 -070039
Romain Guye4d01122010-06-16 18:44:05 -070040/**
41 * An implementation of Canvas on top of OpenGL ES 2.0.
42 */
Romain Guyb051e892010-09-28 19:09:36 -070043class GLES20Canvas extends HardwareCanvas {
Romain Guye4d01122010-06-16 18:44:05 -070044 private final boolean mOpaque;
John Reck44fd8d22014-02-26 11:00:11 -080045 protected long mRenderer;
Patrick Dubroyf890fab2010-12-19 16:47:17 -080046
47 // The native renderer will be destroyed when this object dies.
48 // DO NOT overwrite this reference once it is set.
Romain Guyeea60692011-07-26 20:35:55 -070049 @SuppressWarnings({"unused", "FieldCanBeLocal"})
Patrick Dubroyf890fab2010-12-19 16:47:17 -080050 private CanvasFinalizer mFinalizer;
51
Romain Guye4d01122010-06-16 18:44:05 -070052 private int mWidth;
53 private int mHeight;
Raph Levien051910b2014-06-15 18:25:29 -070054
Romain Guy6410c0a2013-06-17 11:21:58 -070055 private float[] mPoint;
56 private float[] mLine;
Raph Levien051910b2014-06-15 18:25:29 -070057
Romain Guy6410c0a2013-06-17 11:21:58 -070058 private Rect mClipBounds;
59 private RectF mPathBounds;
Romain Guy6926c722010-07-12 20:20:03 -070060
61 private DrawFilter mFilter;
Romain Guyda8532c2010-08-31 11:50:35 -070062
Romain Guy16393512010-08-08 00:14:31 -070063 ///////////////////////////////////////////////////////////////////////////
64 // JNI
65 ///////////////////////////////////////////////////////////////////////////
66
67 private static native boolean nIsAvailable();
68 private static boolean sIsAvailable = nIsAvailable();
69
70 static boolean isAvailable() {
71 return sIsAvailable;
72 }
Romain Guye4d01122010-06-16 18:44:05 -070073
74 ///////////////////////////////////////////////////////////////////////////
75 // Constructors
76 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070077
John Reck84a4c882014-05-30 14:34:03 -070078 // TODO: Merge with GLES20RecordingCanvas
79 protected GLES20Canvas() {
80 mOpaque = false;
81 mRenderer = nCreateDisplayListRenderer();
Romain Guy6c319ca2011-01-11 14:29:25 -080082 setupFinalizer();
83 }
84
85 private void setupFinalizer() {
Romain Guyfb8b7632010-08-23 21:05:08 -070086 if (mRenderer == 0) {
87 throw new IllegalStateException("Could not create GLES20Canvas renderer");
Chet Haase5c13d892010-10-08 08:37:55 -070088 } else {
Jeff Brown162a0212011-07-21 17:02:54 -070089 mFinalizer = new CanvasFinalizer(mRenderer);
Romain Guyfb8b7632010-08-23 21:05:08 -070090 }
Romain Guye4d01122010-06-16 18:44:05 -070091 }
Romain Guye4d01122010-06-16 18:44:05 -070092
Ashok Bhat36bef0b2014-01-20 20:08:01 +000093 private static native long nCreateDisplayListRenderer();
94 private static native void nResetDisplayListRenderer(long renderer);
95 private static native void nDestroyRenderer(long renderer);
Chet Haase5c13d892010-10-08 08:37:55 -070096
Jeff Brown162a0212011-07-21 17:02:54 -070097 private static final class CanvasFinalizer {
Ashok Bhat36bef0b2014-01-20 20:08:01 +000098 private final long mRenderer;
Chet Haase5c13d892010-10-08 08:37:55 -070099
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000100 public CanvasFinalizer(long renderer) {
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800101 mRenderer = renderer;
Chet Haase5c13d892010-10-08 08:37:55 -0700102 }
103
104 @Override
Patrick Dubroyf890fab2010-12-19 16:47:17 -0800105 protected void finalize() throws Throwable {
Romain Guy171c5922011-01-06 10:04:23 -0800106 try {
Jeff Brown162a0212011-07-21 17:02:54 -0700107 nDestroyRenderer(mRenderer);
Romain Guy171c5922011-01-06 10:04:23 -0800108 } finally {
109 super.finalize();
110 }
Romain Guye4d01122010-06-16 18:44:05 -0700111 }
112 }
Romain Guyce0537b2010-06-29 21:05:21 -0700113
Chris Craikba9b6132013-12-15 17:10:19 -0800114 public static void setProperty(String name, String value) {
115 nSetProperty(name, value);
116 }
117
118 private static native void nSetProperty(String name, String value);
119
Romain Guye4d01122010-06-16 18:44:05 -0700120 ///////////////////////////////////////////////////////////////////////////
121 // Canvas management
122 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700123
124 @Override
125 public boolean isOpaque() {
126 return mOpaque;
127 }
128
129 @Override
130 public int getWidth() {
131 return mWidth;
132 }
133
134 @Override
135 public int getHeight() {
136 return mHeight;
137 }
138
Romain Guyf61970fc2011-07-07 14:10:06 -0700139 @Override
140 public int getMaximumBitmapWidth() {
141 return nGetMaximumTextureWidth();
142 }
143
144 @Override
145 public int getMaximumBitmapHeight() {
146 return nGetMaximumTextureHeight();
147 }
148
149 private static native int nGetMaximumTextureWidth();
Romain Guy530041d2012-01-25 18:56:29 -0800150 private static native int nGetMaximumTextureHeight();
Romain Guyf61970fc2011-07-07 14:10:06 -0700151
Romain Guy2bf68f02012-03-02 13:37:47 -0800152 /**
153 * Returns the native OpenGLRenderer object.
154 */
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000155 long getRenderer() {
Romain Guy2bf68f02012-03-02 13:37:47 -0800156 return mRenderer;
157 }
158
Romain Guye4d01122010-06-16 18:44:05 -0700159 ///////////////////////////////////////////////////////////////////////////
160 // Setup
161 ///////////////////////////////////////////////////////////////////////////
162
163 @Override
164 public void setViewport(int width, int height) {
165 mWidth = width;
166 mHeight = height;
167
168 nSetViewport(mRenderer, width, height);
169 }
Raph Levien051910b2014-06-15 18:25:29 -0700170
Chris Craikcce47eb2014-07-16 15:12:15 -0700171 private static native void nSetViewport(long renderer,
172 int width, int height);
173
174 @Override
175 public void setHighContrastText(boolean highContrastText) {
176 nSetHighContrastText(mRenderer, highContrastText);
177 }
178
179 private static native void nSetHighContrastText(long renderer, boolean highContrastText);
Romain Guye4d01122010-06-16 18:44:05 -0700180
Romain Guy7d7b5492011-01-24 16:33:45 -0800181 @Override
Chris Craik8afd0f22014-08-21 17:41:57 -0700182 public void insertReorderBarrier() {
183 nInsertReorderBarrier(mRenderer, true);
184 }
185
186 @Override
187 public void insertInorderBarrier() {
188 nInsertReorderBarrier(mRenderer, false);
189 }
190
191 private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
192
193 @Override
Chet Haase44b2fe32012-06-06 19:03:58 -0700194 public int onPreDraw(Rect dirty) {
Romain Guy7d7b5492011-01-24 16:33:45 -0800195 if (dirty != null) {
Chet Haase44b2fe32012-06-06 19:03:58 -0700196 return nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom,
197 mOpaque);
Romain Guy7d7b5492011-01-24 16:33:45 -0800198 } else {
Chet Haase44b2fe32012-06-06 19:03:58 -0700199 return nPrepare(mRenderer, mOpaque);
Romain Guy7d7b5492011-01-24 16:33:45 -0800200 }
201 }
202
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000203 private static native int nPrepare(long renderer, boolean opaque);
204 private static native int nPrepareDirty(long renderer, int left, int top, int right, int bottom,
Romain Guy7d7b5492011-01-24 16:33:45 -0800205 boolean opaque);
Romain Guye4d01122010-06-16 18:44:05 -0700206
Romain Guyb051e892010-09-28 19:09:36 -0700207 @Override
Gilles Debunneb35ab7b2011-12-05 15:54:00 -0800208 public void onPostDraw() {
Romain Guyb025b9c2010-09-16 14:16:48 -0700209 nFinish(mRenderer);
210 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700211
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000212 private static native void nFinish(long renderer);
Romain Guyb025b9c2010-09-16 14:16:48 -0700213
Romain Guy530041d2012-01-25 18:56:29 -0800214 ///////////////////////////////////////////////////////////////////////////
215 // Functor
216 ///////////////////////////////////////////////////////////////////////////
217
Romain Guyda8532c2010-08-31 11:50:35 -0700218 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000219 public int callDrawGLFunction(long drawGLFunction) {
Chet Haasedaf98e92011-01-10 14:10:36 -0800220 return nCallDrawGLFunction(mRenderer, drawGLFunction);
221 }
222
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000223 private static native int nCallDrawGLFunction(long renderer, long drawGLFunction);
Chet Haasedaf98e92011-01-10 14:10:36 -0800224
Romain Guybdf76092011-07-18 15:00:43 -0700225 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -0700226 // Display list
227 ///////////////////////////////////////////////////////////////////////////
228
John Reck44fd8d22014-02-26 11:00:11 -0800229 protected static native long nFinishRecording(long renderer);
Romain Guy52036b12013-02-14 18:03:37 -0800230
231 @Override
Chris Craika7090e02014-06-20 16:01:00 -0700232 public int drawRenderNode(RenderNode renderNode, Rect dirty, int flags) {
233 return nDrawRenderNode(mRenderer, renderNode.getNativeDisplayList(), dirty, flags);
Romain Guyb051e892010-09-28 19:09:36 -0700234 }
235
Chris Craika7090e02014-06-20 16:01:00 -0700236 private static native int nDrawRenderNode(long renderer, long renderNode,
Chet Haase1271e2c2012-04-20 09:54:27 -0700237 Rect dirty, int flags);
Romain Guyda8532c2010-08-31 11:50:35 -0700238
Romain Guye4d01122010-06-16 18:44:05 -0700239 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800240 // Hardware layer
241 ///////////////////////////////////////////////////////////////////////////
Raph Levien051910b2014-06-15 18:25:29 -0700242
Romain Guyada830f2011-01-13 12:13:20 -0800243 void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
Chris Craika4e16c52013-03-22 10:00:48 -0700244 layer.setLayerPaint(paint);
John Reck04fc5832014-02-05 16:38:25 -0800245 nDrawLayer(mRenderer, layer.getLayer(), x, y);
Romain Guy6c319ca2011-01-11 14:29:25 -0800246 }
247
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000248 private static native void nDrawLayer(long renderer, long layer, float x, float y);
Romain Guyaa6c24c2011-04-28 18:40:04 -0700249
Romain Guy6c319ca2011-01-11 14:29:25 -0800250 ///////////////////////////////////////////////////////////////////////////
Romain Guy6410c0a2013-06-17 11:21:58 -0700251 // Support
252 ///////////////////////////////////////////////////////////////////////////
253
254 private Rect getInternalClipBounds() {
255 if (mClipBounds == null) mClipBounds = new Rect();
256 return mClipBounds;
257 }
258
259
260 private RectF getPathBounds() {
261 if (mPathBounds == null) mPathBounds = new RectF();
262 return mPathBounds;
263 }
264
265 private float[] getPointStorage() {
266 if (mPoint == null) mPoint = new float[2];
267 return mPoint;
268 }
269
270 private float[] getLineStorage() {
271 if (mLine == null) mLine = new float[4];
272 return mLine;
273 }
274
275 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700276 // Clipping
277 ///////////////////////////////////////////////////////////////////////////
278
279 @Override
280 public boolean clipPath(Path path) {
Romain Guy735738c2012-12-03 12:34:51 -0800281 return nClipPath(mRenderer, path.mNativePath, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700282 }
283
284 @Override
285 public boolean clipPath(Path path, Region.Op op) {
Romain Guy735738c2012-12-03 12:34:51 -0800286 return nClipPath(mRenderer, path.mNativePath, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700287 }
288
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000289 private static native boolean nClipPath(long renderer, long path, int op);
Romain Guy735738c2012-12-03 12:34:51 -0800290
Romain Guye4d01122010-06-16 18:44:05 -0700291 @Override
292 public boolean clipRect(float left, float top, float right, float bottom) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700293 return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700294 }
Raph Levien051910b2014-06-15 18:25:29 -0700295
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000296 private static native boolean nClipRect(long renderer, float left, float top,
Romain Guy079ba2c2010-07-16 14:12:24 -0700297 float right, float bottom, int op);
Romain Guye4d01122010-06-16 18:44:05 -0700298
299 @Override
300 public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700301 return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700302 }
303
304 @Override
305 public boolean clipRect(int left, int top, int right, int bottom) {
Chet Haasedaf98e92011-01-10 14:10:36 -0800306 return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700307 }
Raph Levien051910b2014-06-15 18:25:29 -0700308
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000309 private static native boolean nClipRect(long renderer, int left, int top,
Romain Guy735738c2012-12-03 12:34:51 -0800310 int right, int bottom, int op);
Romain Guye4d01122010-06-16 18:44:05 -0700311
312 @Override
313 public boolean clipRect(Rect rect) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700314 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
Raph Levien051910b2014-06-15 18:25:29 -0700315 Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700316 }
317
318 @Override
319 public boolean clipRect(Rect rect, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700320 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700321 }
322
323 @Override
324 public boolean clipRect(RectF rect) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700325 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
326 Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700327 }
328
329 @Override
330 public boolean clipRect(RectF rect, Region.Op op) {
Romain Guy079ba2c2010-07-16 14:12:24 -0700331 return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700332 }
333
334 @Override
335 public boolean clipRegion(Region region) {
Romain Guy735738c2012-12-03 12:34:51 -0800336 return nClipRegion(mRenderer, region.mNativeRegion, Region.Op.INTERSECT.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700337 }
338
339 @Override
340 public boolean clipRegion(Region region, Region.Op op) {
Romain Guy735738c2012-12-03 12:34:51 -0800341 return nClipRegion(mRenderer, region.mNativeRegion, op.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700342 }
343
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000344 private static native boolean nClipRegion(long renderer, long region, int op);
Romain Guy735738c2012-12-03 12:34:51 -0800345
Romain Guye4d01122010-06-16 18:44:05 -0700346 @Override
347 public boolean getClipBounds(Rect bounds) {
Romain Guy9d5316e2010-06-24 19:30:36 -0700348 return nGetClipBounds(mRenderer, bounds);
Romain Guye4d01122010-06-16 18:44:05 -0700349 }
350
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000351 private static native boolean nGetClipBounds(long renderer, Rect bounds);
Romain Guy9d5316e2010-06-24 19:30:36 -0700352
Romain Guye4d01122010-06-16 18:44:05 -0700353 @Override
354 public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
Derek Sollenbergerca79cf62012-08-14 16:44:52 -0400355 return nQuickReject(mRenderer, left, top, right, bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700356 }
Raph Levien051910b2014-06-15 18:25:29 -0700357
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000358 private static native boolean nQuickReject(long renderer, float left, float top,
Derek Sollenbergerca79cf62012-08-14 16:44:52 -0400359 float right, float bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700360
361 @Override
362 public boolean quickReject(Path path, EdgeType type) {
Romain Guy6410c0a2013-06-17 11:21:58 -0700363 RectF pathBounds = getPathBounds();
364 path.computeBounds(pathBounds, true);
365 return nQuickReject(mRenderer, pathBounds.left, pathBounds.top,
366 pathBounds.right, pathBounds.bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700367 }
368
369 @Override
370 public boolean quickReject(RectF rect, EdgeType type) {
Derek Sollenbergerca79cf62012-08-14 16:44:52 -0400371 return nQuickReject(mRenderer, rect.left, rect.top, rect.right, rect.bottom);
Romain Guye4d01122010-06-16 18:44:05 -0700372 }
373
374 ///////////////////////////////////////////////////////////////////////////
375 // Transformations
376 ///////////////////////////////////////////////////////////////////////////
377
378 @Override
379 public void translate(float dx, float dy) {
Romain Guy807daf72011-01-18 11:19:19 -0800380 if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy);
Romain Guye4d01122010-06-16 18:44:05 -0700381 }
Raph Levien051910b2014-06-15 18:25:29 -0700382
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000383 private static native void nTranslate(long renderer, float dx, float dy);
Romain Guye4d01122010-06-16 18:44:05 -0700384
385 @Override
386 public void skew(float sx, float sy) {
Romain Guy807daf72011-01-18 11:19:19 -0800387 nSkew(mRenderer, sx, sy);
Romain Guye4d01122010-06-16 18:44:05 -0700388 }
389
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000390 private static native void nSkew(long renderer, float sx, float sy);
Romain Guy807daf72011-01-18 11:19:19 -0800391
Romain Guye4d01122010-06-16 18:44:05 -0700392 @Override
393 public void rotate(float degrees) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700394 nRotate(mRenderer, degrees);
Romain Guye4d01122010-06-16 18:44:05 -0700395 }
Raph Levien051910b2014-06-15 18:25:29 -0700396
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000397 private static native void nRotate(long renderer, float degrees);
Romain Guye4d01122010-06-16 18:44:05 -0700398
399 @Override
400 public void scale(float sx, float sy) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700401 nScale(mRenderer, sx, sy);
Romain Guye4d01122010-06-16 18:44:05 -0700402 }
Raph Levien051910b2014-06-15 18:25:29 -0700403
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000404 private static native void nScale(long renderer, float sx, float sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700405
Romain Guye4d01122010-06-16 18:44:05 -0700406 @Override
407 public void setMatrix(Matrix matrix) {
Romain Guye7078592011-10-28 14:32:20 -0700408 nSetMatrix(mRenderer, matrix == null ? 0 : matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700409 }
Raph Levien051910b2014-06-15 18:25:29 -0700410
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000411 private static native void nSetMatrix(long renderer, long matrix);
Romain Guye4d01122010-06-16 18:44:05 -0700412
Romain Guy5ff9df62012-01-23 17:09:05 -0800413 @SuppressWarnings("deprecation")
Romain Guye4d01122010-06-16 18:44:05 -0700414 @Override
Romain Guyf6a11b82010-06-23 17:47:49 -0700415 public void getMatrix(Matrix matrix) {
416 nGetMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700417 }
Raph Levien051910b2014-06-15 18:25:29 -0700418
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000419 private static native void nGetMatrix(long renderer, long matrix);
Romain Guye4d01122010-06-16 18:44:05 -0700420
421 @Override
422 public void concat(Matrix matrix) {
Romain Guy4e7b7722013-07-16 13:47:01 -0700423 if (matrix != null) nConcatMatrix(mRenderer, matrix.native_instance);
Romain Guye4d01122010-06-16 18:44:05 -0700424 }
Raph Levien051910b2014-06-15 18:25:29 -0700425
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000426 private static native void nConcatMatrix(long renderer, long matrix);
Raph Levien051910b2014-06-15 18:25:29 -0700427
Romain Guye4d01122010-06-16 18:44:05 -0700428 ///////////////////////////////////////////////////////////////////////////
429 // State management
430 ///////////////////////////////////////////////////////////////////////////
431
432 @Override
433 public int save() {
Romain Guy8aef54f2010-09-01 15:13:49 -0700434 return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
Romain Guye4d01122010-06-16 18:44:05 -0700435 }
Raph Levien051910b2014-06-15 18:25:29 -0700436
Romain Guye4d01122010-06-16 18:44:05 -0700437 @Override
438 public int save(int saveFlags) {
Romain Guybb9524b2010-06-22 18:56:38 -0700439 return nSave(mRenderer, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700440 }
441
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000442 private static native int nSave(long renderer, int flags);
Raph Levien051910b2014-06-15 18:25:29 -0700443
Romain Guye4d01122010-06-16 18:44:05 -0700444 @Override
445 public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
Romain Guy189887e2011-08-25 11:45:13 -0700446 if (bounds != null) {
447 return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
448 }
449
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500450 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
451 return nSaveLayer(mRenderer, nativePaint, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700452 }
453
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000454 private static native int nSaveLayer(long renderer, long paint, int saveFlags);
Romain Guy189887e2011-08-25 11:45:13 -0700455
Romain Guye4d01122010-06-16 18:44:05 -0700456 @Override
457 public int saveLayer(float left, float top, float right, float bottom, Paint paint,
458 int saveFlags) {
Romain Guy01d58e42011-01-19 21:54:02 -0800459 if (left < right && top < bottom) {
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500460 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
461 return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
Romain Guy01d58e42011-01-19 21:54:02 -0800462 }
463 return save(saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700464 }
465
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000466 private static native int nSaveLayer(long renderer, float left, float top,
467 float right, float bottom, long paint, int saveFlags);
Romain Guybd6b79b2010-06-26 00:13:53 -0700468
Romain Guye4d01122010-06-16 18:44:05 -0700469 @Override
470 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
Romain Guy189887e2011-08-25 11:45:13 -0700471 if (bounds != null) {
472 return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
473 alpha, saveFlags);
474 }
475 return nSaveLayerAlpha(mRenderer, alpha, saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700476 }
477
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000478 private static native int nSaveLayerAlpha(long renderer, int alpha, int saveFlags);
Romain Guy189887e2011-08-25 11:45:13 -0700479
Romain Guye4d01122010-06-16 18:44:05 -0700480 @Override
481 public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
482 int saveFlags) {
Romain Guy01d58e42011-01-19 21:54:02 -0800483 if (left < right && top < bottom) {
484 return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
485 }
486 return save(saveFlags);
Romain Guye4d01122010-06-16 18:44:05 -0700487 }
488
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000489 private static native int nSaveLayerAlpha(long renderer, float left, float top, float right,
Romain Guybd6b79b2010-06-26 00:13:53 -0700490 float bottom, int alpha, int saveFlags);
Raph Levien051910b2014-06-15 18:25:29 -0700491
Romain Guye4d01122010-06-16 18:44:05 -0700492 @Override
493 public void restore() {
Romain Guybb9524b2010-06-22 18:56:38 -0700494 nRestore(mRenderer);
Romain Guye4d01122010-06-16 18:44:05 -0700495 }
Raph Levien051910b2014-06-15 18:25:29 -0700496
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000497 private static native void nRestore(long renderer);
Romain Guye4d01122010-06-16 18:44:05 -0700498
499 @Override
500 public void restoreToCount(int saveCount) {
Romain Guybb9524b2010-06-22 18:56:38 -0700501 nRestoreToCount(mRenderer, saveCount);
Romain Guye4d01122010-06-16 18:44:05 -0700502 }
503
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000504 private static native void nRestoreToCount(long renderer, int saveCount);
Raph Levien051910b2014-06-15 18:25:29 -0700505
Romain Guye4d01122010-06-16 18:44:05 -0700506 @Override
507 public int getSaveCount() {
Romain Guybb9524b2010-06-22 18:56:38 -0700508 return nGetSaveCount(mRenderer);
Romain Guye4d01122010-06-16 18:44:05 -0700509 }
Raph Levien051910b2014-06-15 18:25:29 -0700510
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000511 private static native int nGetSaveCount(long renderer);
Romain Guye4d01122010-06-16 18:44:05 -0700512
513 ///////////////////////////////////////////////////////////////////////////
514 // Filtering
515 ///////////////////////////////////////////////////////////////////////////
516
517 @Override
518 public void setDrawFilter(DrawFilter filter) {
Romain Guy6926c722010-07-12 20:20:03 -0700519 mFilter = filter;
Romain Guy5ff9df62012-01-23 17:09:05 -0800520 if (filter == null) {
521 nResetPaintFilter(mRenderer);
522 } else if (filter instanceof PaintFlagsDrawFilter) {
523 PaintFlagsDrawFilter flagsFilter = (PaintFlagsDrawFilter) filter;
524 nSetupPaintFilter(mRenderer, flagsFilter.clearBits, flagsFilter.setBits);
525 }
Romain Guye4d01122010-06-16 18:44:05 -0700526 }
527
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000528 private static native void nResetPaintFilter(long renderer);
529 private static native void nSetupPaintFilter(long renderer, int clearBits, int setBits);
Romain Guy5ff9df62012-01-23 17:09:05 -0800530
Romain Guye4d01122010-06-16 18:44:05 -0700531 @Override
532 public DrawFilter getDrawFilter() {
Romain Guy6926c722010-07-12 20:20:03 -0700533 return mFilter;
Romain Guye4d01122010-06-16 18:44:05 -0700534 }
535
536 ///////////////////////////////////////////////////////////////////////////
537 // Drawing
538 ///////////////////////////////////////////////////////////////////////////
539
540 @Override
Antonio Calabrese24609582014-06-12 16:32:03 -0700541 public void drawArc(float left, float top, float right, float bottom,
542 float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
543 nDrawArc(mRenderer, left, top, right, bottom,
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400544 startAngle, sweepAngle, useCenter, paint.mNativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700545 }
546
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000547 private static native void nDrawArc(long renderer, float left, float top,
Romain Guy7d7b5492011-01-24 16:33:45 -0800548 float right, float bottom, float startAngle, float sweepAngle,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000549 boolean useCenter, long paint);
Romain Guy8b2f5262011-01-23 16:15:02 -0800550
Romain Guye4d01122010-06-16 18:44:05 -0700551 @Override
552 public void drawARGB(int a, int r, int g, int b) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700553 drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
Romain Guye4d01122010-06-16 18:44:05 -0700554 }
555
556 @Override
Romain Guyf3187b72013-06-07 12:17:11 -0700557 public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
558 Bitmap bitmap = patch.getBitmap();
Chris Craik1abf5d62013-08-16 12:47:03 -0700559 throwIfCannotDraw(bitmap);
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500560 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
561 nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
562 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guyf3187b72013-06-07 12:17:11 -0700563 }
564
565 @Override
Romain Guy3b748a42013-04-17 18:54:38 -0700566 public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
567 Bitmap bitmap = patch.getBitmap();
Chris Craik1abf5d62013-08-16 12:47:03 -0700568 throwIfCannotDraw(bitmap);
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500569 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
570 nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
571 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guydeba7852010-07-07 17:54:48 -0700572 }
573
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000574 private static native void nDrawPatch(long renderer, long bitmap, byte[] buffer, long chunk,
575 float left, float top, float right, float bottom, long paint);
Romain Guydeba7852010-07-07 17:54:48 -0700576
577 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700578 public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700579 throwIfCannotDraw(bitmap);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400580 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
581 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700582 }
583
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000584 private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
585 float left, float top, long paint);
Romain Guydbd77cd2010-07-09 10:36:05 -0700586
Romain Guye4d01122010-06-16 18:44:05 -0700587 @Override
588 public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700589 throwIfCannotDraw(bitmap);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400590 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
591 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
592 matrix.native_instance, nativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700593 }
594
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000595 private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
596 long matrix, long 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) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700600 throwIfCannotDraw(bitmap);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400601 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
Romain Guy694b5192010-07-21 21:33:20 -0700602
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400603 int left, top, right, bottom;
604 if (src == null) {
605 left = top = 0;
606 right = bitmap.getWidth();
607 bottom = bitmap.getHeight();
608 } else {
609 left = src.left;
610 right = src.right;
611 top = src.top;
612 bottom = src.bottom;
Romain Guy694b5192010-07-21 21:33:20 -0700613 }
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400614
615 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
616 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700617 }
618
619 @Override
620 public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700621 throwIfCannotDraw(bitmap);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400622 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
623
624 float left, top, right, bottom;
625 if (src == null) {
626 left = top = 0;
627 right = bitmap.getWidth();
628 bottom = bitmap.getHeight();
629 } else {
630 left = src.left;
631 right = src.right;
632 top = src.top;
633 bottom = src.bottom;
Romain Guyff98fa52011-11-28 09:35:09 -0800634 }
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400635
636 nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
637 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700638 }
639
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000640 private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
Romain Guyce0537b2010-06-29 21:05:21 -0700641 float srcLeft, float srcTop, float srcRight, float srcBottom,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000642 float left, float top, float right, float bottom, long paint);
Romain Guyce0537b2010-06-29 21:05:21 -0700643
Romain Guye4d01122010-06-16 18:44:05 -0700644 @Override
645 public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
646 int width, int height, boolean hasAlpha, Paint paint) {
Romain Guye651cc62012-05-14 19:44:40 -0700647 if (width < 0) {
648 throw new IllegalArgumentException("width must be >= 0");
649 }
650
651 if (height < 0) {
652 throw new IllegalArgumentException("height must be >= 0");
653 }
654
655 if (Math.abs(stride) < width) {
656 throw new IllegalArgumentException("abs(stride) must be >= width");
657 }
658
659 int lastScanline = offset + (height - 1) * stride;
660 int length = colors.length;
661
662 if (offset < 0 || (offset + width > length) || lastScanline < 0 ||
663 (lastScanline + width > length)) {
664 throw new ArrayIndexOutOfBoundsException();
665 }
666
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500667 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
668 nDrawBitmap(mRenderer, colors, offset, stride, x, y,
669 width, height, hasAlpha, nativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700670 }
671
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000672 private static native void nDrawBitmap(long renderer, int[] colors, int offset, int stride,
673 float x, float y, int width, int height, boolean hasAlpha, long nativePaint);
Romain Guye651cc62012-05-14 19:44:40 -0700674
Romain Guye4d01122010-06-16 18:44:05 -0700675 @Override
676 public void drawBitmap(int[] colors, int offset, int stride, int x, int y,
677 int width, int height, boolean hasAlpha, Paint paint) {
Romain Guyce0537b2010-06-29 21:05:21 -0700678 drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700679 }
680
681 @Override
682 public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
683 int vertOffset, int[] colors, int colorOffset, Paint paint) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700684 throwIfCannotDraw(bitmap);
Romain Guy5a7b4662011-01-20 19:09:30 -0800685 if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
686 throw new ArrayIndexOutOfBoundsException();
687 }
688
689 if (meshWidth == 0 || meshHeight == 0) {
690 return;
691 }
692
693 final int count = (meshWidth + 1) * (meshHeight + 1);
694 checkRange(verts.length, vertOffset, count * 2);
695
Romain Guyff316ec2013-02-13 18:39:43 -0800696 if (colors != null) {
697 checkRange(colors.length, colorOffset, count);
698 }
Romain Guy5a7b4662011-01-20 19:09:30 -0800699
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400700 final long nativePaint = paint == null ? 0 : paint.mNativePaint;
701 nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
702 verts, vertOffset, colors, colorOffset, nativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700703 }
704
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000705 private static native void nDrawBitmapMesh(long renderer, long bitmap, byte[] buffer,
Romain Guy5a7b4662011-01-20 19:09:30 -0800706 int meshWidth, int meshHeight, float[] verts, int vertOffset,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000707 int[] colors, int colorOffset, long paint);
Romain Guy5a7b4662011-01-20 19:09:30 -0800708
Romain Guye4d01122010-06-16 18:44:05 -0700709 @Override
710 public void drawCircle(float cx, float cy, float radius, Paint paint) {
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400711 nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700712 }
713
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000714 private static native void nDrawCircle(long renderer, float cx, float cy,
715 float radius, long paint);
Romain Guy01d58e42011-01-19 21:54:02 -0800716
Romain Guye4d01122010-06-16 18:44:05 -0700717 @Override
John Reck52244ff2014-05-01 21:27:37 -0700718 public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
719 CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
720 nDrawCircle(mRenderer, cx.getNativeContainer(), cy.getNativeContainer(),
721 radius.getNativeContainer(), paint.getNativeContainer());
722 }
723
724 private static native void nDrawCircle(long renderer, long propCx,
725 long propCy, long propRadius, long propPaint);
726
727 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700728 public void drawColor(int color) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700729 drawColor(color, PorterDuff.Mode.SRC_OVER);
Romain Guye4d01122010-06-16 18:44:05 -0700730 }
731
732 @Override
733 public void drawColor(int color, PorterDuff.Mode mode) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700734 nDrawColor(mRenderer, color, mode.nativeInt);
Romain Guye4d01122010-06-16 18:44:05 -0700735 }
Raph Levien051910b2014-06-15 18:25:29 -0700736
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000737 private static native void nDrawColor(long renderer, int color, int mode);
Romain Guye4d01122010-06-16 18:44:05 -0700738
739 @Override
740 public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
Romain Guy6410c0a2013-06-17 11:21:58 -0700741 float[] line = getLineStorage();
742 line[0] = startX;
743 line[1] = startY;
744 line[2] = stopX;
745 line[3] = stopY;
746 drawLines(line, 0, 4, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700747 }
748
749 @Override
750 public void drawLines(float[] pts, int offset, int count, Paint paint) {
Chris Craik5d116762013-02-19 17:49:31 -0800751 if (count < 4) return;
752
Romain Guy759ea802010-09-16 20:49:46 -0700753 if ((offset | count) < 0 || offset + count > pts.length) {
754 throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
755 }
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400756 nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700757 }
758
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000759 private static native void nDrawLines(long renderer, float[] points,
760 int offset, int count, long paint);
Romain Guy759ea802010-09-16 20:49:46 -0700761
Romain Guye4d01122010-06-16 18:44:05 -0700762 @Override
763 public void drawLines(float[] pts, Paint paint) {
Romain Guy759ea802010-09-16 20:49:46 -0700764 drawLines(pts, 0, pts.length, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700765 }
766
767 @Override
Antonio Calabrese24609582014-06-12 16:32:03 -0700768 public void drawOval(float left, float top, float right, float bottom, Paint paint) {
769 nDrawOval(mRenderer, left, top, right, bottom, paint.mNativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700770 }
771
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000772 private static native void nDrawOval(long renderer, float left, float top,
773 float right, float bottom, long paint);
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800774
Romain Guye4d01122010-06-16 18:44:05 -0700775 @Override
776 public void drawPaint(Paint paint) {
Romain Guy6410c0a2013-06-17 11:21:58 -0700777 final Rect r = getInternalClipBounds();
Romain Guy6926c722010-07-12 20:20:03 -0700778 nGetClipBounds(mRenderer, r);
779 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700780 }
781
782 @Override
783 public void drawPath(Path path, Paint paint) {
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400784 if (path.isSimplePath) {
785 if (path.rects != null) {
786 nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
Romain Guya48a1a82010-08-10 14:59:15 -0700787 }
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400788 } else {
789 nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
Romain Guya48a1a82010-08-10 14:59:15 -0700790 }
Romain Guye4d01122010-06-16 18:44:05 -0700791 }
792
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000793 private static native void nDrawPath(long renderer, long path, long paint);
794 private static native void nDrawRects(long renderer, long region, long paint);
Romain Guy7fbcc042010-08-04 15:40:07 -0700795
Romain Guye4d01122010-06-16 18:44:05 -0700796 @Override
797 public void drawPicture(Picture picture) {
Romain Guy75582e82012-01-18 18:13:35 -0800798 picture.endRecording();
799 // TODO: Implement rendering
Romain Guye4d01122010-06-16 18:44:05 -0700800 }
801
802 @Override
803 public void drawPicture(Picture picture, Rect dst) {
Romain Guy75582e82012-01-18 18:13:35 -0800804 save();
805 translate(dst.left, dst.top);
806 if (picture.getWidth() > 0 && picture.getHeight() > 0) {
807 scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
808 }
809 drawPicture(picture);
810 restore();
Romain Guye4d01122010-06-16 18:44:05 -0700811 }
812
813 @Override
814 public void drawPicture(Picture picture, RectF dst) {
Romain Guy75582e82012-01-18 18:13:35 -0800815 save();
816 translate(dst.left, dst.top);
817 if (picture.getWidth() > 0 && picture.getHeight() > 0) {
818 scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
819 }
820 drawPicture(picture);
821 restore();
Romain Guye4d01122010-06-16 18:44:05 -0700822 }
823
824 @Override
825 public void drawPoint(float x, float y, Paint paint) {
Romain Guy6410c0a2013-06-17 11:21:58 -0700826 float[] point = getPointStorage();
827 point[0] = x;
828 point[1] = y;
829 drawPoints(point, 0, 2, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700830 }
831
832 @Override
833 public void drawPoints(float[] pts, Paint paint) {
Romain Guyed6fcb02011-03-21 13:11:28 -0700834 drawPoints(pts, 0, pts.length, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700835 }
836
837 @Override
Romain Guyed6fcb02011-03-21 13:11:28 -0700838 public void drawPoints(float[] pts, int offset, int count, Paint paint) {
Chris Craik5d116762013-02-19 17:49:31 -0800839 if (count < 2) return;
840
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400841 nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
Romain Guyed6fcb02011-03-21 13:11:28 -0700842 }
843
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000844 private static native void nDrawPoints(long renderer, float[] points,
845 int offset, int count, long paint);
Romain Guyed6fcb02011-03-21 13:11:28 -0700846
Raph Levien3f0d6162014-06-17 20:59:42 -0700847 // Note: drawPosText just uses implementation in Canvas
Romain Guyeb9a5362012-01-17 17:39:26 -0800848
Romain Guye4d01122010-06-16 18:44:05 -0700849 @Override
850 public void drawRect(float left, float top, float right, float bottom, Paint paint) {
Romain Guy765dcf32012-02-27 13:28:22 -0800851 if (left == right || top == bottom) return;
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400852 nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700853 }
854
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000855 private static native void nDrawRect(long renderer, float left, float top,
856 float right, float bottom, long paint);
Romain Guyc7d53492010-06-25 13:41:57 -0700857
Romain Guye4d01122010-06-16 18:44:05 -0700858 @Override
859 public void drawRect(Rect r, Paint paint) {
Romain Guyc7d53492010-06-25 13:41:57 -0700860 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700861 }
862
863 @Override
Romain Guyc7d53492010-06-25 13:41:57 -0700864 public void drawRect(RectF r, Paint paint) {
865 drawRect(r.left, r.top, r.right, r.bottom, paint);
Romain Guye4d01122010-06-16 18:44:05 -0700866 }
867
868 @Override
869 public void drawRGB(int r, int g, int b) {
Romain Guy85bf02f2010-06-22 13:11:24 -0700870 drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
Romain Guye4d01122010-06-16 18:44:05 -0700871 }
872
873 @Override
Chris Craik4d1c1532014-04-24 14:13:40 -0700874 public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
875 Paint paint) {
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400876 nDrawRoundRect(mRenderer, left, top, right, bottom, rx, ry, paint.mNativePaint);
Romain Guye4d01122010-06-16 18:44:05 -0700877 }
878
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000879 private static native void nDrawRoundRect(long renderer, float left, float top,
880 float right, float bottom, float rx, float y, long paint);
Romain Guy01d58e42011-01-19 21:54:02 -0800881
Romain Guye4d01122010-06-16 18:44:05 -0700882 @Override
883 public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
Romain Guya1db5742010-07-20 13:09:13 -0700884 if ((index | count | (index + count) | (text.length - index - count)) < 0) {
885 throw new IndexOutOfBoundsException();
886 }
Romain Guy61c8c9c2010-08-09 20:48:09 -0700887
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400888 nDrawText(mRenderer, text, index, count, x, y,
889 paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
Romain Guye4d01122010-06-16 18:44:05 -0700890 }
Raph Levien051910b2014-06-15 18:25:29 -0700891
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000892 private static native void nDrawText(long renderer, char[] text, int index, int count,
Raph Levien1a73f7322014-01-30 16:06:28 -0800893 float x, float y, int bidiFlags, long paint, long typeface);
Romain Guye4d01122010-06-16 18:44:05 -0700894
895 @Override
896 public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400897 if (text instanceof String || text instanceof SpannedString ||
898 text instanceof SpannableString) {
899 nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
900 paint.mNativePaint, paint.mNativeTypeface);
901 } else if (text instanceof GraphicsOperations) {
902 ((GraphicsOperations) text).drawText(this, start, end, x, y, paint);
903 } else {
904 char[] buf = TemporaryBuffer.obtain(end - start);
905 TextUtils.getChars(text, start, end, buf, 0);
906 nDrawText(mRenderer, buf, 0, end - start, x, y,
907 paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
908 TemporaryBuffer.recycle(buf);
Romain Guya1db5742010-07-20 13:09:13 -0700909 }
Romain Guye4d01122010-06-16 18:44:05 -0700910 }
911
912 @Override
913 public void drawText(String text, int start, int end, float x, float y, Paint paint) {
Romain Guya1db5742010-07-20 13:09:13 -0700914 if ((start | end | (end - start) | (text.length() - end)) < 0) {
915 throw new IndexOutOfBoundsException();
916 }
Romain Guy61c8c9c2010-08-09 20:48:09 -0700917
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400918 nDrawText(mRenderer, text, start, end, x, y,
919 paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
Romain Guye4d01122010-06-16 18:44:05 -0700920 }
921
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000922 private static native void nDrawText(long renderer, String text, int start, int end,
Raph Levien1a73f7322014-01-30 16:06:28 -0800923 float x, float y, int bidiFlags, long paint, long typeface);
Romain Guya1db5742010-07-20 13:09:13 -0700924
Romain Guye4d01122010-06-16 18:44:05 -0700925 @Override
926 public void drawText(String text, float x, float y, Paint paint) {
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400927 nDrawText(mRenderer, text, 0, text.length(), x, y,
928 paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
Romain Guye4d01122010-06-16 18:44:05 -0700929 }
930
931 @Override
932 public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
933 float vOffset, Paint paint) {
Romain Guy325740f2012-02-24 16:48:34 -0800934 if (index < 0 || index + count > text.length) {
935 throw new ArrayIndexOutOfBoundsException();
936 }
937
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400938 nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700939 paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
Romain Guye4d01122010-06-16 18:44:05 -0700940 }
941
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000942 private static native void nDrawTextOnPath(long renderer, char[] text, int index, int count,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700943 long path, float hOffset, float vOffset, int bidiFlags, long nativePaint,
944 long typeface);
Romain Guy325740f2012-02-24 16:48:34 -0800945
Romain Guye4d01122010-06-16 18:44:05 -0700946 @Override
947 public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
Romain Guy325740f2012-02-24 16:48:34 -0800948 if (text.length() == 0) return;
949
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400950 nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700951 paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
Romain Guye4d01122010-06-16 18:44:05 -0700952 }
953
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000954 private static native void nDrawTextOnPath(long renderer, String text, int start, int end,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700955 long path, float hOffset, float vOffset, int bidiFlags, long nativePaint,
956 long typeface);
Romain Guy325740f2012-02-24 16:48:34 -0800957
Romain Guye4d01122010-06-16 18:44:05 -0700958 @Override
959 public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
Raph Levien051910b2014-06-15 18:25:29 -0700960 float x, float y, boolean isRtl, Paint paint) {
Romain Guy61c8c9c2010-08-09 20:48:09 -0700961 if ((index | count | text.length - index - count) < 0) {
962 throw new IndexOutOfBoundsException();
963 }
Romain Guy61c8c9c2010-08-09 20:48:09 -0700964
Raph Levien051910b2014-06-15 18:25:29 -0700965 nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, isRtl,
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400966 paint.mNativePaint, paint.mNativeTypeface);
Romain Guye4d01122010-06-16 18:44:05 -0700967 }
968
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000969 private static native void nDrawTextRun(long renderer, char[] text, int index, int count,
Raph Levien051910b2014-06-15 18:25:29 -0700970 int contextIndex, int contextCount, float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700971
Romain Guye4d01122010-06-16 18:44:05 -0700972 @Override
973 public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
Raph Levien051910b2014-06-15 18:25:29 -0700974 float x, float y, boolean isRtl, Paint paint) {
Romain Guy61c8c9c2010-08-09 20:48:09 -0700975 if ((start | end | end - start | text.length() - end) < 0) {
976 throw new IndexOutOfBoundsException();
977 }
978
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400979 if (text instanceof String || text instanceof SpannedString ||
980 text instanceof SpannableString) {
981 nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
Raph Levien051910b2014-06-15 18:25:29 -0700982 contextEnd, x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400983 } else if (text instanceof GraphicsOperations) {
984 ((GraphicsOperations) text).drawTextRun(this, start, end,
Raph Levien051910b2014-06-15 18:25:29 -0700985 contextStart, contextEnd, x, y, isRtl, paint);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400986 } else {
987 int contextLen = contextEnd - contextStart;
988 int len = end - start;
989 char[] buf = TemporaryBuffer.obtain(contextLen);
990 TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
991 nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
Raph Levien051910b2014-06-15 18:25:29 -0700992 x, y, isRtl, paint.mNativePaint, paint.mNativeTypeface);
Leon Scroggins IIId1ad5e62014-05-05 12:50:38 -0400993 TemporaryBuffer.recycle(buf);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700994 }
Romain Guye4d01122010-06-16 18:44:05 -0700995 }
996
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000997 private static native void nDrawTextRun(long renderer, String text, int start, int end,
Raph Levien051910b2014-06-15 18:25:29 -0700998 int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700999
Romain Guye4d01122010-06-16 18:44:05 -07001000 @Override
1001 public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
1002 float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
1003 int indexOffset, int indexCount, Paint paint) {
Romain Guy6926c722010-07-12 20:20:03 -07001004 // TODO: Implement
Romain Guye4d01122010-06-16 18:44:05 -07001005 }
Romain Guye4d01122010-06-16 18:44:05 -07001006}