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