1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view; 18 19 import android.annotation.ColorInt; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.Size; 23 import android.graphics.BaseCanvas; 24 import android.graphics.Bitmap; 25 import android.graphics.Canvas; 26 import android.graphics.Color; 27 import android.graphics.Matrix; 28 import android.graphics.NinePatch; 29 import android.graphics.Paint; 30 import android.graphics.Path; 31 import android.graphics.Picture; 32 import android.graphics.PorterDuff; 33 import android.graphics.Rect; 34 import android.graphics.RectF; 35 import android.graphics.TemporaryBuffer; 36 import android.text.GraphicsOperations; 37 import android.text.SpannableString; 38 import android.text.SpannedString; 39 import android.text.TextUtils; 40 41 import dalvik.annotation.optimization.FastNative; 42 43 /** 44 * This class is a base class for canvases that defer drawing operations, so all 45 * the draw operations can be marked @FastNative. It contains a re-implementation of 46 * all the methods in {@link BaseCanvas}. 47 * 48 * @hide 49 */ 50 public class RecordingCanvas extends Canvas { 51 RecordingCanvas(long nativeCanvas)52 public RecordingCanvas(long nativeCanvas) { 53 super(nativeCanvas); 54 } 55 56 @Override drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)57 public final void drawArc(float left, float top, float right, float bottom, float startAngle, 58 float sweepAngle, boolean useCenter, @NonNull Paint paint) { 59 nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle, 60 useCenter, paint.getNativeInstance()); 61 } 62 63 @Override drawArc(@onNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)64 public final void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, 65 boolean useCenter, @NonNull Paint paint) { 66 drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter, 67 paint); 68 } 69 70 @Override drawARGB(int a, int r, int g, int b)71 public final void drawARGB(int a, int r, int g, int b) { 72 drawColor(Color.argb(a, r, g, b)); 73 } 74 75 @Override drawBitmap(@onNull Bitmap bitmap, float left, float top, @Nullable Paint paint)76 public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top, 77 @Nullable Paint paint) { 78 throwIfCannotDraw(bitmap); 79 nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, 80 paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, 81 bitmap.mDensity); 82 } 83 84 @Override drawBitmap(@onNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint)85 public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, 86 @Nullable Paint paint) { 87 nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(), 88 paint != null ? paint.getNativeInstance() : 0); 89 } 90 91 @Override drawBitmap(@onNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst, @Nullable Paint paint)92 public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst, 93 @Nullable Paint paint) { 94 if (dst == null) { 95 throw new NullPointerException(); 96 } 97 throwIfCannotDraw(bitmap); 98 final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); 99 100 int left, top, right, bottom; 101 if (src == null) { 102 left = top = 0; 103 right = bitmap.getWidth(); 104 bottom = bitmap.getHeight(); 105 } else { 106 left = src.left; 107 right = src.right; 108 top = src.top; 109 bottom = src.bottom; 110 } 111 112 nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom, 113 dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity, 114 bitmap.mDensity); 115 } 116 117 @Override drawBitmap(@onNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst, @Nullable Paint paint)118 public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst, 119 @Nullable Paint paint) { 120 if (dst == null) { 121 throw new NullPointerException(); 122 } 123 throwIfCannotDraw(bitmap); 124 final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); 125 126 float left, top, right, bottom; 127 if (src == null) { 128 left = top = 0; 129 right = bitmap.getWidth(); 130 bottom = bitmap.getHeight(); 131 } else { 132 left = src.left; 133 right = src.right; 134 top = src.top; 135 bottom = src.bottom; 136 } 137 138 nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom, 139 dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity, 140 bitmap.mDensity); 141 } 142 143 /** @deprecated checkstyle */ 144 @Override 145 @Deprecated drawBitmap(@onNull int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, @Nullable Paint paint)146 public final void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y, 147 int width, int height, boolean hasAlpha, @Nullable Paint paint) { 148 // check for valid input 149 if (width < 0) { 150 throw new IllegalArgumentException("width must be >= 0"); 151 } 152 if (height < 0) { 153 throw new IllegalArgumentException("height must be >= 0"); 154 } 155 if (Math.abs(stride) < width) { 156 throw new IllegalArgumentException("abs(stride) must be >= width"); 157 } 158 int lastScanline = offset + (height - 1) * stride; 159 int length = colors.length; 160 if (offset < 0 || (offset + width > length) || lastScanline < 0 161 || (lastScanline + width > length)) { 162 throw new ArrayIndexOutOfBoundsException(); 163 } 164 // quick escape if there's nothing to draw 165 if (width == 0 || height == 0) { 166 return; 167 } 168 // punch down to native for the actual draw 169 nDrawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha, 170 paint != null ? paint.getNativeInstance() : 0); 171 } 172 173 /** @deprecated checkstyle */ 174 @Override 175 @Deprecated drawBitmap(@onNull int[] colors, int offset, int stride, int x, int y, int width, int height, boolean hasAlpha, @Nullable Paint paint)176 public final void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y, 177 int width, int height, boolean hasAlpha, @Nullable Paint paint) { 178 // call through to the common float version 179 drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, 180 hasAlpha, paint); 181 } 182 183 @Override drawBitmapMesh(@onNull Bitmap bitmap, int meshWidth, int meshHeight, @NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset, @Nullable Paint paint)184 public final void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight, 185 @NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset, 186 @Nullable Paint paint) { 187 if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) { 188 throw new ArrayIndexOutOfBoundsException(); 189 } 190 if (meshWidth == 0 || meshHeight == 0) { 191 return; 192 } 193 int count = (meshWidth + 1) * (meshHeight + 1); 194 // we mul by 2 since we need two floats per vertex 195 checkRange(verts.length, vertOffset, count * 2); 196 if (colors != null) { 197 // no mul by 2, since we need only 1 color per vertex 198 checkRange(colors.length, colorOffset, count); 199 } 200 nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight, 201 verts, vertOffset, colors, colorOffset, 202 paint != null ? paint.getNativeInstance() : 0); 203 } 204 205 @Override drawCircle(float cx, float cy, float radius, @NonNull Paint paint)206 public final void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) { 207 nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance()); 208 } 209 210 @Override drawColor(@olorInt int color)211 public final void drawColor(@ColorInt int color) { 212 nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt); 213 } 214 215 @Override drawColor(@olorInt int color, @NonNull PorterDuff.Mode mode)216 public final void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) { 217 nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt); 218 } 219 220 @Override drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint)221 public final void drawLine(float startX, float startY, float stopX, float stopY, 222 @NonNull Paint paint) { 223 nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance()); 224 } 225 226 @Override drawLines(@izemultiple = 4) @onNull float[] pts, int offset, int count, @NonNull Paint paint)227 public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count, 228 @NonNull Paint paint) { 229 nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance()); 230 } 231 232 @Override drawLines(@izemultiple = 4) @onNull float[] pts, @NonNull Paint paint)233 public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) { 234 drawLines(pts, 0, pts.length, paint); 235 } 236 237 @Override drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)238 public final void drawOval(float left, float top, float right, float bottom, 239 @NonNull Paint paint) { 240 nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance()); 241 } 242 243 @Override drawOval(@onNull RectF oval, @NonNull Paint paint)244 public final void drawOval(@NonNull RectF oval, @NonNull Paint paint) { 245 if (oval == null) { 246 throw new NullPointerException(); 247 } 248 drawOval(oval.left, oval.top, oval.right, oval.bottom, paint); 249 } 250 251 @Override drawPaint(@onNull Paint paint)252 public final void drawPaint(@NonNull Paint paint) { 253 nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance()); 254 } 255 256 @Override drawPatch(@onNull NinePatch patch, @NonNull Rect dst, @Nullable Paint paint)257 public final void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst, 258 @Nullable Paint paint) { 259 Bitmap bitmap = patch.getBitmap(); 260 throwIfCannotDraw(bitmap); 261 final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); 262 nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk, 263 dst.left, dst.top, dst.right, dst.bottom, nativePaint, 264 mDensity, patch.getDensity()); 265 } 266 267 @Override drawPatch(@onNull NinePatch patch, @NonNull RectF dst, @Nullable Paint paint)268 public final void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst, 269 @Nullable Paint paint) { 270 Bitmap bitmap = patch.getBitmap(); 271 throwIfCannotDraw(bitmap); 272 final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); 273 nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk, 274 dst.left, dst.top, dst.right, dst.bottom, nativePaint, 275 mDensity, patch.getDensity()); 276 } 277 278 @Override drawPath(@onNull Path path, @NonNull Paint paint)279 public final void drawPath(@NonNull Path path, @NonNull Paint paint) { 280 if (path.isSimplePath && path.rects != null) { 281 nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance()); 282 } else { 283 nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance()); 284 } 285 } 286 287 @Override drawPicture(@onNull Picture picture)288 public final void drawPicture(@NonNull Picture picture) { 289 picture.endRecording(); 290 int restoreCount = save(); 291 picture.draw(this); 292 restoreToCount(restoreCount); 293 } 294 295 @Override drawPicture(@onNull Picture picture, @NonNull Rect dst)296 public final void drawPicture(@NonNull Picture picture, @NonNull Rect dst) { 297 save(); 298 translate(dst.left, dst.top); 299 if (picture.getWidth() > 0 && picture.getHeight() > 0) { 300 scale((float) dst.width() / picture.getWidth(), 301 (float) dst.height() / picture.getHeight()); 302 } 303 drawPicture(picture); 304 restore(); 305 } 306 307 @Override drawPicture(@onNull Picture picture, @NonNull RectF dst)308 public final void drawPicture(@NonNull Picture picture, @NonNull RectF dst) { 309 save(); 310 translate(dst.left, dst.top); 311 if (picture.getWidth() > 0 && picture.getHeight() > 0) { 312 scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight()); 313 } 314 drawPicture(picture); 315 restore(); 316 } 317 318 @Override drawPoint(float x, float y, @NonNull Paint paint)319 public final void drawPoint(float x, float y, @NonNull Paint paint) { 320 nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance()); 321 } 322 323 @Override drawPoints(@izemultiple = 2) float[] pts, int offset, int count, @NonNull Paint paint)324 public final void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count, 325 @NonNull Paint paint) { 326 nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance()); 327 } 328 329 @Override drawPoints(@izemultiple = 2) @onNull float[] pts, @NonNull Paint paint)330 public final void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) { 331 drawPoints(pts, 0, pts.length, paint); 332 } 333 334 /** @deprecated checkstyle */ 335 @Override 336 @Deprecated drawPosText(@onNull char[] text, int index, int count, @NonNull @Size(multiple = 2) float[] pos, @NonNull Paint paint)337 public final void drawPosText(@NonNull char[] text, int index, int count, 338 @NonNull @Size(multiple = 2) float[] pos, 339 @NonNull Paint paint) { 340 if (index < 0 || index + count > text.length || count * 2 > pos.length) { 341 throw new IndexOutOfBoundsException(); 342 } 343 for (int i = 0; i < count; i++) { 344 drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint); 345 } 346 } 347 348 /** @deprecated checkstyle */ 349 @Override 350 @Deprecated drawPosText(@onNull String text, @NonNull @Size(multiple = 2) float[] pos, @NonNull Paint paint)351 public final void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos, 352 @NonNull Paint paint) { 353 drawPosText(text.toCharArray(), 0, text.length(), pos, paint); 354 } 355 356 @Override drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)357 public final void drawRect(float left, float top, float right, float bottom, 358 @NonNull Paint paint) { 359 nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance()); 360 } 361 362 @Override drawRect(@onNull Rect r, @NonNull Paint paint)363 public final void drawRect(@NonNull Rect r, @NonNull Paint paint) { 364 drawRect(r.left, r.top, r.right, r.bottom, paint); 365 } 366 367 @Override drawRect(@onNull RectF rect, @NonNull Paint paint)368 public final void drawRect(@NonNull RectF rect, @NonNull Paint paint) { 369 nDrawRect(mNativeCanvasWrapper, 370 rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance()); 371 } 372 373 @Override drawRGB(int r, int g, int b)374 public final void drawRGB(int r, int g, int b) { 375 drawColor(Color.rgb(r, g, b)); 376 } 377 378 @Override drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, @NonNull Paint paint)379 public final void drawRoundRect(float left, float top, float right, float bottom, 380 float rx, float ry, @NonNull Paint paint) { 381 nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, 382 paint.getNativeInstance()); 383 } 384 385 @Override drawRoundRect(@onNull RectF rect, float rx, float ry, @NonNull Paint paint)386 public final void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) { 387 drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint); 388 } 389 390 @Override drawText(@onNull char[] text, int index, int count, float x, float y, @NonNull Paint paint)391 public final void drawText(@NonNull char[] text, int index, int count, float x, float y, 392 @NonNull Paint paint) { 393 if ((index | count | (index + count) 394 | (text.length - index - count)) < 0) { 395 throw new IndexOutOfBoundsException(); 396 } 397 nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags, 398 paint.getNativeInstance(), paint.mNativeTypeface); 399 } 400 401 @Override drawText(@onNull CharSequence text, int start, int end, float x, float y, @NonNull Paint paint)402 public final void drawText(@NonNull CharSequence text, int start, int end, float x, float y, 403 @NonNull Paint paint) { 404 if ((start | end | (end - start) | (text.length() - end)) < 0) { 405 throw new IndexOutOfBoundsException(); 406 } 407 if (text instanceof String || text instanceof SpannedString 408 || text instanceof SpannableString) { 409 nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y, 410 paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); 411 } else if (text instanceof GraphicsOperations) { 412 ((GraphicsOperations) text).drawText(this, start, end, x, y, 413 paint); 414 } else { 415 char[] buf = TemporaryBuffer.obtain(end - start); 416 TextUtils.getChars(text, start, end, buf, 0); 417 nDrawText(mNativeCanvasWrapper, buf, 0, end - start, x, y, 418 paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); 419 TemporaryBuffer.recycle(buf); 420 } 421 } 422 423 @Override drawText(@onNull String text, float x, float y, @NonNull Paint paint)424 public final void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) { 425 nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags, 426 paint.getNativeInstance(), paint.mNativeTypeface); 427 } 428 429 @Override drawText(@onNull String text, int start, int end, float x, float y, @NonNull Paint paint)430 public final void drawText(@NonNull String text, int start, int end, float x, float y, 431 @NonNull Paint paint) { 432 if ((start | end | (end - start) | (text.length() - end)) < 0) { 433 throw new IndexOutOfBoundsException(); 434 } 435 nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags, 436 paint.getNativeInstance(), paint.mNativeTypeface); 437 } 438 439 @Override drawTextOnPath(@onNull char[] text, int index, int count, @NonNull Path path, float hOffset, float vOffset, @NonNull Paint paint)440 public final void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path, 441 float hOffset, float vOffset, @NonNull Paint paint) { 442 if (index < 0 || index + count > text.length) { 443 throw new ArrayIndexOutOfBoundsException(); 444 } 445 nDrawTextOnPath(mNativeCanvasWrapper, text, index, count, 446 path.readOnlyNI(), hOffset, vOffset, 447 paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); 448 } 449 450 @Override drawTextOnPath(@onNull String text, @NonNull Path path, float hOffset, float vOffset, @NonNull Paint paint)451 public final void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset, 452 float vOffset, @NonNull Paint paint) { 453 if (text.length() > 0) { 454 nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset, 455 paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); 456 } 457 } 458 459 @Override drawTextRun(@onNull char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint)460 public final void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex, 461 int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) { 462 463 if (text == null) { 464 throw new NullPointerException("text is null"); 465 } 466 if (paint == null) { 467 throw new NullPointerException("paint is null"); 468 } 469 if ((index | count | contextIndex | contextCount | index - contextIndex 470 | (contextIndex + contextCount) - (index + count) 471 | text.length - (contextIndex + contextCount)) < 0) { 472 throw new IndexOutOfBoundsException(); 473 } 474 475 nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount, 476 x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface); 477 } 478 479 @Override drawTextRun(@onNull CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint)480 public final void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart, 481 int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) { 482 483 if (text == null) { 484 throw new NullPointerException("text is null"); 485 } 486 if (paint == null) { 487 throw new NullPointerException("paint is null"); 488 } 489 if ((start | end | contextStart | contextEnd | start - contextStart | end - start 490 | contextEnd - end | text.length() - contextEnd) < 0) { 491 throw new IndexOutOfBoundsException(); 492 } 493 494 if (text instanceof String || text instanceof SpannedString 495 || text instanceof SpannableString) { 496 nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart, 497 contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface); 498 } else if (text instanceof GraphicsOperations) { 499 ((GraphicsOperations) text).drawTextRun(this, start, end, 500 contextStart, contextEnd, x, y, isRtl, paint); 501 } else { 502 int contextLen = contextEnd - contextStart; 503 int len = end - start; 504 char[] buf = TemporaryBuffer.obtain(contextLen); 505 TextUtils.getChars(text, contextStart, contextEnd, buf, 0); 506 nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len, 507 0, contextLen, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface); 508 TemporaryBuffer.recycle(buf); 509 } 510 } 511 512 @Override drawVertices(@onNull VertexMode mode, int vertexCount, @NonNull float[] verts, int vertOffset, @Nullable float[] texs, int texOffset, @Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount, @NonNull Paint paint)513 public final void drawVertices(@NonNull VertexMode mode, int vertexCount, 514 @NonNull float[] verts, int vertOffset, @Nullable float[] texs, int texOffset, 515 @Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset, 516 int indexCount, @NonNull Paint paint) { 517 checkRange(verts.length, vertOffset, vertexCount); 518 if (isHardwareAccelerated()) { 519 return; 520 } 521 if (texs != null) { 522 checkRange(texs.length, texOffset, vertexCount); 523 } 524 if (colors != null) { 525 checkRange(colors.length, colorOffset, vertexCount / 2); 526 } 527 if (indices != null) { 528 checkRange(indices.length, indexOffset, indexCount); 529 } 530 nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts, 531 vertOffset, texs, texOffset, colors, colorOffset, 532 indices, indexOffset, indexCount, paint.getNativeInstance()); 533 } 534 535 @FastNative nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top, long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity)536 private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top, 537 long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity); 538 539 @FastNative nDrawBitmap(long nativeCanvas, Bitmap bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity)540 private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, 541 float srcLeft, float srcTop, float srcRight, float srcBottom, 542 float dstLeft, float dstTop, float dstRight, float dstBottom, 543 long nativePaintOrZero, int screenDensity, int bitmapDensity); 544 545 @FastNative nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero)546 private static native void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride, 547 float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero); 548 549 @FastNative nDrawColor(long nativeCanvas, int color, int mode)550 private static native void nDrawColor(long nativeCanvas, int color, int mode); 551 552 @FastNative nDrawPaint(long nativeCanvas, long nativePaint)553 private static native void nDrawPaint(long nativeCanvas, long nativePaint); 554 555 @FastNative nDrawPoint(long canvasHandle, float x, float y, long paintHandle)556 private static native void nDrawPoint(long canvasHandle, float x, float y, long paintHandle); 557 558 @FastNative nDrawPoints(long canvasHandle, float[] pts, int offset, int count, long paintHandle)559 private static native void nDrawPoints(long canvasHandle, float[] pts, int offset, int count, 560 long paintHandle); 561 562 @FastNative nDrawLine(long nativeCanvas, float startX, float startY, float stopX, float stopY, long nativePaint)563 private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX, 564 float stopY, long nativePaint); 565 566 @FastNative nDrawLines(long canvasHandle, float[] pts, int offset, int count, long paintHandle)567 private static native void nDrawLines(long canvasHandle, float[] pts, int offset, int count, 568 long paintHandle); 569 570 @FastNative nDrawRect(long nativeCanvas, float left, float top, float right, float bottom, long nativePaint)571 private static native void nDrawRect(long nativeCanvas, float left, float top, float right, 572 float bottom, long nativePaint); 573 574 @FastNative nDrawOval(long nativeCanvas, float left, float top, float right, float bottom, long nativePaint)575 private static native void nDrawOval(long nativeCanvas, float left, float top, float right, 576 float bottom, long nativePaint); 577 578 @FastNative nDrawCircle(long nativeCanvas, float cx, float cy, float radius, long nativePaint)579 private static native void nDrawCircle(long nativeCanvas, float cx, float cy, float radius, 580 long nativePaint); 581 582 @FastNative nDrawArc(long nativeCanvas, float left, float top, float right, float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint)583 private static native void nDrawArc(long nativeCanvas, float left, float top, float right, 584 float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint); 585 586 @FastNative nDrawRoundRect(long nativeCanvas, float left, float top, float right, float bottom, float rx, float ry, long nativePaint)587 private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right, 588 float bottom, float rx, float ry, long nativePaint); 589 590 @FastNative nDrawPath(long nativeCanvas, long nativePath, long nativePaint)591 private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint); 592 593 @FastNative nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint)594 private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint); 595 596 @FastNative nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch, float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity)597 private static native void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch, 598 float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero, 599 int screenDensity, int bitmapDensity); 600 601 @FastNative nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap, long nativeMatrix, long nativePaint)602 private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap, 603 long nativeMatrix, long nativePaint); 604 605 @FastNative nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, long nativePaint)606 private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth, 607 int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, 608 long nativePaint); 609 610 @FastNative nDrawVertices(long nativeCanvas, int mode, int n, float[] verts, int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, int indexOffset, int indexCount, long nativePaint)611 private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts, 612 int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, 613 short[] indices, int indexOffset, int indexCount, long nativePaint); 614 615 @FastNative nDrawText(long nativeCanvas, char[] text, int index, int count, float x, float y, int flags, long nativePaint, long nativeTypeface)616 private static native void nDrawText(long nativeCanvas, char[] text, int index, int count, 617 float x, float y, int flags, long nativePaint, long nativeTypeface); 618 619 @FastNative nDrawText(long nativeCanvas, String text, int start, int end, float x, float y, int flags, long nativePaint, long nativeTypeface)620 private static native void nDrawText(long nativeCanvas, String text, int start, int end, 621 float x, float y, int flags, long nativePaint, long nativeTypeface); 622 623 @FastNative nDrawTextRun(long nativeCanvas, String text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint, long nativeTypeface)624 private static native void nDrawTextRun(long nativeCanvas, String text, int start, int end, 625 int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint, 626 long nativeTypeface); 627 628 @FastNative nDrawTextRun(long nativeCanvas, char[] text, int start, int count, int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint, long nativeTypeface)629 private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count, 630 int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint, 631 long nativeTypeface); 632 633 @FastNative nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count, long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint, long nativeTypeface)634 private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count, 635 long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint, 636 long nativeTypeface); 637 638 @FastNative nDrawTextOnPath(long nativeCanvas, String text, long nativePath, float hOffset, float vOffset, int flags, long nativePaint, long nativeTypeface)639 private static native void nDrawTextOnPath(long nativeCanvas, String text, long nativePath, 640 float hOffset, float vOffset, int flags, long nativePaint, long nativeTypeface); 641 } 642