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