1 /* 2 * Copyright (C) 2006 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.text.GraphicsOperations; 20 import android.text.SpannableString; 21 import android.text.SpannedString; 22 import android.text.TextUtils; 23 24 import javax.microedition.khronos.opengles.GL; 25 26 /** 27 * The Canvas class holds the "draw" calls. To draw something, you need 28 * 4 basic components: A Bitmap to hold the pixels, a Canvas to host 29 * the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, 30 * Path, text, Bitmap), and a paint (to describe the colors and styles for the 31 * drawing). 32 * 33 * <div class="special reference"> 34 * <h3>Developer Guides</h3> 35 * <p>For more information about how to use Canvas, read the 36 * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html"> 37 * Canvas and Drawables</a> developer guide.</p></div> 38 */ 39 public class Canvas { 40 // assigned in constructors or setBitmap, freed in finalizer 41 int mNativeCanvas; 42 43 // may be null 44 private Bitmap mBitmap; 45 46 // optional field set by the caller 47 private DrawFilter mDrawFilter; 48 49 /** 50 * @hide 51 */ 52 protected int mDensity = Bitmap.DENSITY_NONE; 53 54 /** 55 * Used to determine when compatibility scaling is in effect. 56 * 57 * @hide 58 */ 59 protected int mScreenDensity = Bitmap.DENSITY_NONE; 60 61 // Used by native code 62 @SuppressWarnings({"UnusedDeclaration"}) 63 private int mSurfaceFormat; 64 65 /** 66 * Flag for drawTextRun indicating left-to-right run direction. 67 * @hide 68 */ 69 public static final int DIRECTION_LTR = 0; 70 71 /** 72 * Flag for drawTextRun indicating right-to-left run direction. 73 * @hide 74 */ 75 public static final int DIRECTION_RTL = 1; 76 77 // Maximum bitmap size as defined in Skia's native code 78 // (see SkCanvas.cpp, SkDraw.cpp) 79 private static final int MAXMIMUM_BITMAP_SIZE = 32766; 80 81 // This field is used to finalize the native Canvas properly 82 @SuppressWarnings({"UnusedDeclaration"}) 83 private final CanvasFinalizer mFinalizer; 84 85 private static class CanvasFinalizer { 86 private int mNativeCanvas; 87 CanvasFinalizer(int nativeCanvas)88 public CanvasFinalizer(int nativeCanvas) { 89 mNativeCanvas = nativeCanvas; 90 } 91 92 @Override finalize()93 protected void finalize() throws Throwable { 94 try { 95 if (mNativeCanvas != 0) { 96 finalizer(mNativeCanvas); 97 } 98 } finally { 99 super.finalize(); 100 } 101 } 102 } 103 104 /** 105 * Construct an empty raster canvas. Use setBitmap() to specify a bitmap to 106 * draw into. The initial target density is {@link Bitmap#DENSITY_NONE}; 107 * this will typically be replaced when a target bitmap is set for the 108 * canvas. 109 */ Canvas()110 public Canvas() { 111 // 0 means no native bitmap 112 mNativeCanvas = initRaster(0); 113 mFinalizer = new CanvasFinalizer(mNativeCanvas); 114 } 115 116 /** 117 * Construct a canvas with the specified bitmap to draw into. The bitmap 118 * must be mutable. 119 * 120 * <p>The initial target density of the canvas is the same as the given 121 * bitmap's density. 122 * 123 * @param bitmap Specifies a mutable bitmap for the canvas to draw into. 124 */ Canvas(Bitmap bitmap)125 public Canvas(Bitmap bitmap) { 126 if (!bitmap.isMutable()) { 127 throw new IllegalStateException("Immutable bitmap passed to Canvas constructor"); 128 } 129 throwIfRecycled(bitmap); 130 mNativeCanvas = initRaster(bitmap.ni()); 131 mFinalizer = new CanvasFinalizer(mNativeCanvas); 132 mBitmap = bitmap; 133 mDensity = bitmap.mDensity; 134 } 135 Canvas(int nativeCanvas)136 Canvas(int nativeCanvas) { 137 if (nativeCanvas == 0) { 138 throw new IllegalStateException(); 139 } 140 mNativeCanvas = nativeCanvas; 141 mFinalizer = new CanvasFinalizer(nativeCanvas); 142 mDensity = Bitmap.getDefaultDensity(); 143 } 144 145 /** 146 * Replace existing canvas while ensuring that the swap has occurred before 147 * the previous native canvas is unreferenced. 148 */ safeCanvasSwap(int nativeCanvas, boolean copyState)149 private void safeCanvasSwap(int nativeCanvas, boolean copyState) { 150 final int oldCanvas = mNativeCanvas; 151 mNativeCanvas = nativeCanvas; 152 mFinalizer.mNativeCanvas = nativeCanvas; 153 if (copyState) { 154 copyNativeCanvasState(oldCanvas, mNativeCanvas); 155 } 156 finalizer(oldCanvas); 157 } 158 159 /** 160 * Returns null. 161 * 162 * @deprecated This method is not supported and should not be invoked. 163 * 164 * @hide 165 */ 166 @Deprecated getGL()167 protected GL getGL() { 168 return null; 169 } 170 171 /** 172 * Indicates whether this Canvas uses hardware acceleration. 173 * 174 * Note that this method does not define what type of hardware acceleration 175 * may or may not be used. 176 * 177 * @return True if drawing operations are hardware accelerated, 178 * false otherwise. 179 */ isHardwareAccelerated()180 public boolean isHardwareAccelerated() { 181 return false; 182 } 183 184 /** 185 * Specify a bitmap for the canvas to draw into. All canvas state such as 186 * layers, filters, and the save/restore stack are reset with the exception 187 * of the current matrix and clip stack. Additionally, as a side-effect 188 * the canvas' target density is updated to match that of the bitmap. 189 * 190 * @param bitmap Specifies a mutable bitmap for the canvas to draw into. 191 * @see #setDensity(int) 192 * @see #getDensity() 193 */ setBitmap(Bitmap bitmap)194 public void setBitmap(Bitmap bitmap) { 195 if (isHardwareAccelerated()) { 196 throw new RuntimeException("Can't set a bitmap device on a GL canvas"); 197 } 198 199 if (bitmap == null) { 200 safeCanvasSwap(initRaster(0), false); 201 mDensity = Bitmap.DENSITY_NONE; 202 } else { 203 if (!bitmap.isMutable()) { 204 throw new IllegalStateException(); 205 } 206 throwIfRecycled(bitmap); 207 208 safeCanvasSwap(initRaster(bitmap.ni()), true); 209 mDensity = bitmap.mDensity; 210 } 211 212 mBitmap = bitmap; 213 } 214 215 /** 216 * Set the viewport dimensions if this canvas is GL based. If it is not, 217 * this method is ignored and no exception is thrown. 218 * 219 * @param width The width of the viewport 220 * @param height The height of the viewport 221 * 222 * @hide 223 */ setViewport(int width, int height)224 public void setViewport(int width, int height) { 225 } 226 227 /** 228 * Return true if the device that the current layer draws into is opaque 229 * (i.e. does not support per-pixel alpha). 230 * 231 * @return true if the device that the current layer draws into is opaque 232 */ isOpaque()233 public native boolean isOpaque(); 234 235 /** 236 * Returns the width of the current drawing layer 237 * 238 * @return the width of the current drawing layer 239 */ getWidth()240 public native int getWidth(); 241 242 /** 243 * Returns the height of the current drawing layer 244 * 245 * @return the height of the current drawing layer 246 */ getHeight()247 public native int getHeight(); 248 249 /** 250 * <p>Returns the target density of the canvas. The default density is 251 * derived from the density of its backing bitmap, or 252 * {@link Bitmap#DENSITY_NONE} if there is not one.</p> 253 * 254 * @return Returns the current target density of the canvas, which is used 255 * to determine the scaling factor when drawing a bitmap into it. 256 * 257 * @see #setDensity(int) 258 * @see Bitmap#getDensity() 259 */ getDensity()260 public int getDensity() { 261 return mDensity; 262 } 263 264 /** 265 * <p>Specifies the density for this Canvas' backing bitmap. This modifies 266 * the target density of the canvas itself, as well as the density of its 267 * backing bitmap via {@link Bitmap#setDensity(int) Bitmap.setDensity(int)}. 268 * 269 * @param density The new target density of the canvas, which is used 270 * to determine the scaling factor when drawing a bitmap into it. Use 271 * {@link Bitmap#DENSITY_NONE} to disable bitmap scaling. 272 * 273 * @see #getDensity() 274 * @see Bitmap#setDensity(int) 275 */ setDensity(int density)276 public void setDensity(int density) { 277 if (mBitmap != null) { 278 mBitmap.setDensity(density); 279 } 280 mDensity = density; 281 } 282 283 /** @hide */ setScreenDensity(int density)284 public void setScreenDensity(int density) { 285 mScreenDensity = density; 286 } 287 288 /** 289 * Returns the maximum allowed width for bitmaps drawn with this canvas. 290 * Attempting to draw with a bitmap wider than this value will result 291 * in an error. 292 * 293 * @see #getMaximumBitmapHeight() 294 */ getMaximumBitmapWidth()295 public int getMaximumBitmapWidth() { 296 return MAXMIMUM_BITMAP_SIZE; 297 } 298 299 /** 300 * Returns the maximum allowed height for bitmaps drawn with this canvas. 301 * Attempting to draw with a bitmap taller than this value will result 302 * in an error. 303 * 304 * @see #getMaximumBitmapWidth() 305 */ getMaximumBitmapHeight()306 public int getMaximumBitmapHeight() { 307 return MAXMIMUM_BITMAP_SIZE; 308 } 309 310 // the SAVE_FLAG constants must match their native equivalents 311 312 /** restore the current matrix when restore() is called */ 313 public static final int MATRIX_SAVE_FLAG = 0x01; 314 /** restore the current clip when restore() is called */ 315 public static final int CLIP_SAVE_FLAG = 0x02; 316 /** the layer needs to per-pixel alpha */ 317 public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04; 318 /** the layer needs to 8-bits per color component */ 319 public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08; 320 /** clip against the layer's bounds */ 321 public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10; 322 /** restore everything when restore() is called */ 323 public static final int ALL_SAVE_FLAG = 0x1F; 324 325 /** 326 * Saves the current matrix and clip onto a private stack. Subsequent 327 * calls to translate,scale,rotate,skew,concat or clipRect,clipPath 328 * will all operate as usual, but when the balancing call to restore() 329 * is made, those calls will be forgotten, and the settings that existed 330 * before the save() will be reinstated. 331 * 332 * @return The value to pass to restoreToCount() to balance this save() 333 */ save()334 public native int save(); 335 336 /** 337 * Based on saveFlags, can save the current matrix and clip onto a private 338 * stack. Subsequent calls to translate,scale,rotate,skew,concat or 339 * clipRect,clipPath will all operate as usual, but when the balancing 340 * call to restore() is made, those calls will be forgotten, and the 341 * settings that existed before the save() will be reinstated. 342 * 343 * @param saveFlags flag bits that specify which parts of the Canvas state 344 * to save/restore 345 * @return The value to pass to restoreToCount() to balance this save() 346 */ save(int saveFlags)347 public native int save(int saveFlags); 348 349 /** 350 * This behaves the same as save(), but in addition it allocates an 351 * offscreen bitmap. All drawing calls are directed there, and only when 352 * the balancing call to restore() is made is that offscreen transfered to 353 * the canvas (or the previous layer). Subsequent calls to translate, 354 * scale, rotate, skew, concat or clipRect, clipPath all operate on this 355 * copy. When the balancing call to restore() is made, this copy is 356 * deleted and the previous matrix/clip state is restored. 357 * 358 * @param bounds May be null. The maximum size the offscreen bitmap 359 * needs to be (in local coordinates) 360 * @param paint This is copied, and is applied to the offscreen when 361 * restore() is called. 362 * @param saveFlags see _SAVE_FLAG constants 363 * @return value to pass to restoreToCount() to balance this save() 364 */ saveLayer(RectF bounds, Paint paint, int saveFlags)365 public int saveLayer(RectF bounds, Paint paint, int saveFlags) { 366 return native_saveLayer(mNativeCanvas, bounds, 367 paint != null ? paint.mNativePaint : 0, 368 saveFlags); 369 } 370 371 /** 372 * Helper version of saveLayer() that takes 4 values rather than a RectF. 373 */ saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags)374 public int saveLayer(float left, float top, float right, float bottom, Paint paint, 375 int saveFlags) { 376 return native_saveLayer(mNativeCanvas, left, top, right, bottom, 377 paint != null ? paint.mNativePaint : 0, 378 saveFlags); 379 } 380 381 /** 382 * This behaves the same as save(), but in addition it allocates an 383 * offscreen bitmap. All drawing calls are directed there, and only when 384 * the balancing call to restore() is made is that offscreen transfered to 385 * the canvas (or the previous layer). Subsequent calls to translate, 386 * scale, rotate, skew, concat or clipRect, clipPath all operate on this 387 * copy. When the balancing call to restore() is made, this copy is 388 * deleted and the previous matrix/clip state is restored. 389 * 390 * @param bounds The maximum size the offscreen bitmap needs to be 391 * (in local coordinates) 392 * @param alpha The alpha to apply to the offscreen when when it is 393 drawn during restore() 394 * @param saveFlags see _SAVE_FLAG constants 395 * @return value to pass to restoreToCount() to balance this call 396 */ saveLayerAlpha(RectF bounds, int alpha, int saveFlags)397 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { 398 alpha = Math.min(255, Math.max(0, alpha)); 399 return native_saveLayerAlpha(mNativeCanvas, bounds, alpha, saveFlags); 400 } 401 402 /** 403 * Helper for saveLayerAlpha() that takes 4 values instead of a RectF. 404 */ saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int saveFlags)405 public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, 406 int saveFlags) { 407 return native_saveLayerAlpha(mNativeCanvas, left, top, right, bottom, 408 alpha, saveFlags); 409 } 410 411 /** 412 * This call balances a previous call to save(), and is used to remove all 413 * modifications to the matrix/clip state since the last save call. It is 414 * an error to call restore() more times than save() was called. 415 */ restore()416 public native void restore(); 417 418 /** 419 * Returns the number of matrix/clip states on the Canvas' private stack. 420 * This will equal # save() calls - # restore() calls. 421 */ getSaveCount()422 public native int getSaveCount(); 423 424 /** 425 * Efficient way to pop any calls to save() that happened after the save 426 * count reached saveCount. It is an error for saveCount to be less than 1. 427 * 428 * Example: 429 * int count = canvas.save(); 430 * ... // more calls potentially to save() 431 * canvas.restoreToCount(count); 432 * // now the canvas is back in the same state it was before the initial 433 * // call to save(). 434 * 435 * @param saveCount The save level to restore to. 436 */ restoreToCount(int saveCount)437 public native void restoreToCount(int saveCount); 438 439 /** 440 * Preconcat the current matrix with the specified translation 441 * 442 * @param dx The distance to translate in X 443 * @param dy The distance to translate in Y 444 */ translate(float dx, float dy)445 public native void translate(float dx, float dy); 446 447 /** 448 * Preconcat the current matrix with the specified scale. 449 * 450 * @param sx The amount to scale in X 451 * @param sy The amount to scale in Y 452 */ scale(float sx, float sy)453 public native void scale(float sx, float sy); 454 455 /** 456 * Preconcat the current matrix with the specified scale. 457 * 458 * @param sx The amount to scale in X 459 * @param sy The amount to scale in Y 460 * @param px The x-coord for the pivot point (unchanged by the scale) 461 * @param py The y-coord for the pivot point (unchanged by the scale) 462 */ scale(float sx, float sy, float px, float py)463 public final void scale(float sx, float sy, float px, float py) { 464 translate(px, py); 465 scale(sx, sy); 466 translate(-px, -py); 467 } 468 469 /** 470 * Preconcat the current matrix with the specified rotation. 471 * 472 * @param degrees The amount to rotate, in degrees 473 */ rotate(float degrees)474 public native void rotate(float degrees); 475 476 /** 477 * Preconcat the current matrix with the specified rotation. 478 * 479 * @param degrees The amount to rotate, in degrees 480 * @param px The x-coord for the pivot point (unchanged by the rotation) 481 * @param py The y-coord for the pivot point (unchanged by the rotation) 482 */ rotate(float degrees, float px, float py)483 public final void rotate(float degrees, float px, float py) { 484 translate(px, py); 485 rotate(degrees); 486 translate(-px, -py); 487 } 488 489 /** 490 * Preconcat the current matrix with the specified skew. 491 * 492 * @param sx The amount to skew in X 493 * @param sy The amount to skew in Y 494 */ skew(float sx, float sy)495 public native void skew(float sx, float sy); 496 497 /** 498 * Preconcat the current matrix with the specified matrix. 499 * 500 * @param matrix The matrix to preconcatenate with the current matrix 501 */ concat(Matrix matrix)502 public void concat(Matrix matrix) { 503 native_concat(mNativeCanvas, matrix.native_instance); 504 } 505 506 /** 507 * Completely replace the current matrix with the specified matrix. If the 508 * matrix parameter is null, then the current matrix is reset to identity. 509 * 510 * <strong>Note:</strong> it is recommended to use {@link #concat(Matrix)}, 511 * {@link #scale(float, float)}, {@link #translate(float, float)} and 512 * {@link #rotate(float)} instead of this method. 513 * 514 * @param matrix The matrix to replace the current matrix with. If it is 515 * null, set the current matrix to identity. 516 * 517 * @see #concat(Matrix) 518 */ setMatrix(Matrix matrix)519 public void setMatrix(Matrix matrix) { 520 native_setMatrix(mNativeCanvas, 521 matrix == null ? 0 : matrix.native_instance); 522 } 523 524 /** 525 * Return, in ctm, the current transformation matrix. This does not alter 526 * the matrix in the canvas, but just returns a copy of it. 527 */ 528 @Deprecated getMatrix(Matrix ctm)529 public void getMatrix(Matrix ctm) { 530 native_getCTM(mNativeCanvas, ctm.native_instance); 531 } 532 533 /** 534 * Return a new matrix with a copy of the canvas' current transformation 535 * matrix. 536 */ 537 @Deprecated getMatrix()538 public final Matrix getMatrix() { 539 Matrix m = new Matrix(); 540 //noinspection deprecation 541 getMatrix(m); 542 return m; 543 } 544 545 /** 546 * Modify the current clip with the specified rectangle. 547 * 548 * @param rect The rect to intersect with the current clip 549 * @param op How the clip is modified 550 * @return true if the resulting clip is non-empty 551 */ clipRect(RectF rect, Region.Op op)552 public boolean clipRect(RectF rect, Region.Op op) { 553 return native_clipRect(mNativeCanvas, rect.left, rect.top, rect.right, rect.bottom, 554 op.nativeInt); 555 } 556 557 /** 558 * Modify the current clip with the specified rectangle, which is 559 * expressed in local coordinates. 560 * 561 * @param rect The rectangle to intersect with the current clip. 562 * @param op How the clip is modified 563 * @return true if the resulting clip is non-empty 564 */ clipRect(Rect rect, Region.Op op)565 public boolean clipRect(Rect rect, Region.Op op) { 566 return native_clipRect(mNativeCanvas, rect.left, rect.top, rect.right, rect.bottom, 567 op.nativeInt); 568 } 569 570 /** 571 * Intersect the current clip with the specified rectangle, which is 572 * expressed in local coordinates. 573 * 574 * @param rect The rectangle to intersect with the current clip. 575 * @return true if the resulting clip is non-empty 576 */ clipRect(RectF rect)577 public native boolean clipRect(RectF rect); 578 579 /** 580 * Intersect the current clip with the specified rectangle, which is 581 * expressed in local coordinates. 582 * 583 * @param rect The rectangle to intersect with the current clip. 584 * @return true if the resulting clip is non-empty 585 */ clipRect(Rect rect)586 public native boolean clipRect(Rect rect); 587 588 /** 589 * Modify the current clip with the specified rectangle, which is 590 * expressed in local coordinates. 591 * 592 * @param left The left side of the rectangle to intersect with the 593 * current clip 594 * @param top The top of the rectangle to intersect with the current 595 * clip 596 * @param right The right side of the rectangle to intersect with the 597 * current clip 598 * @param bottom The bottom of the rectangle to intersect with the current 599 * clip 600 * @param op How the clip is modified 601 * @return true if the resulting clip is non-empty 602 */ clipRect(float left, float top, float right, float bottom, Region.Op op)603 public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) { 604 return native_clipRect(mNativeCanvas, left, top, right, bottom, op.nativeInt); 605 } 606 607 /** 608 * Intersect the current clip with the specified rectangle, which is 609 * expressed in local coordinates. 610 * 611 * @param left The left side of the rectangle to intersect with the 612 * current clip 613 * @param top The top of the rectangle to intersect with the current clip 614 * @param right The right side of the rectangle to intersect with the 615 * current clip 616 * @param bottom The bottom of the rectangle to intersect with the current 617 * clip 618 * @return true if the resulting clip is non-empty 619 */ clipRect(float left, float top, float right, float bottom)620 public native boolean clipRect(float left, float top, float right, float bottom); 621 622 /** 623 * Intersect the current clip with the specified rectangle, which is 624 * expressed in local coordinates. 625 * 626 * @param left The left side of the rectangle to intersect with the 627 * current clip 628 * @param top The top of the rectangle to intersect with the current clip 629 * @param right The right side of the rectangle to intersect with the 630 * current clip 631 * @param bottom The bottom of the rectangle to intersect with the current 632 * clip 633 * @return true if the resulting clip is non-empty 634 */ clipRect(int left, int top, int right, int bottom)635 public native boolean clipRect(int left, int top, int right, int bottom); 636 637 /** 638 * Modify the current clip with the specified path. 639 * 640 * @param path The path to operate on the current clip 641 * @param op How the clip is modified 642 * @return true if the resulting is non-empty 643 */ clipPath(Path path, Region.Op op)644 public boolean clipPath(Path path, Region.Op op) { 645 return native_clipPath(mNativeCanvas, path.ni(), op.nativeInt); 646 } 647 648 /** 649 * Intersect the current clip with the specified path. 650 * 651 * @param path The path to intersect with the current clip 652 * @return true if the resulting is non-empty 653 */ clipPath(Path path)654 public boolean clipPath(Path path) { 655 return clipPath(path, Region.Op.INTERSECT); 656 } 657 658 /** 659 * Modify the current clip with the specified region. Note that unlike 660 * clipRect() and clipPath() which transform their arguments by the 661 * current matrix, clipRegion() assumes its argument is already in the 662 * coordinate system of the current layer's bitmap, and so not 663 * transformation is performed. 664 * 665 * @param region The region to operate on the current clip, based on op 666 * @param op How the clip is modified 667 * @return true if the resulting is non-empty 668 */ clipRegion(Region region, Region.Op op)669 public boolean clipRegion(Region region, Region.Op op) { 670 return native_clipRegion(mNativeCanvas, region.ni(), op.nativeInt); 671 } 672 673 /** 674 * Intersect the current clip with the specified region. Note that unlike 675 * clipRect() and clipPath() which transform their arguments by the 676 * current matrix, clipRegion() assumes its argument is already in the 677 * coordinate system of the current layer's bitmap, and so not 678 * transformation is performed. 679 * 680 * @param region The region to operate on the current clip, based on op 681 * @return true if the resulting is non-empty 682 */ clipRegion(Region region)683 public boolean clipRegion(Region region) { 684 return clipRegion(region, Region.Op.INTERSECT); 685 } 686 getDrawFilter()687 public DrawFilter getDrawFilter() { 688 return mDrawFilter; 689 } 690 setDrawFilter(DrawFilter filter)691 public void setDrawFilter(DrawFilter filter) { 692 int nativeFilter = 0; 693 if (filter != null) { 694 nativeFilter = filter.mNativeInt; 695 } 696 mDrawFilter = filter; 697 nativeSetDrawFilter(mNativeCanvas, nativeFilter); 698 } 699 700 public enum EdgeType { 701 702 /** 703 * Black-and-White: Treat edges by just rounding to nearest pixel boundary 704 */ 705 BW(0), //!< treat edges by just rounding to nearest pixel boundary 706 707 /** 708 * Antialiased: Treat edges by rounding-out, since they may be antialiased 709 */ 710 AA(1); 711 EdgeType(int nativeInt)712 EdgeType(int nativeInt) { 713 this.nativeInt = nativeInt; 714 } 715 716 /** 717 * @hide 718 */ 719 public final int nativeInt; 720 } 721 722 /** 723 * Return true if the specified rectangle, after being transformed by the 724 * current matrix, would lie completely outside of the current clip. Call 725 * this to check if an area you intend to draw into is clipped out (and 726 * therefore you can skip making the draw calls). 727 * 728 * @param rect the rect to compare with the current clip 729 * @param type {@link Canvas.EdgeType#AA} if the path should be considered antialiased, 730 * since that means it may affect a larger area (more pixels) than 731 * non-antialiased ({@link Canvas.EdgeType#BW}). 732 * @return true if the rect (transformed by the canvas' matrix) 733 * does not intersect with the canvas' clip 734 */ quickReject(RectF rect, EdgeType type)735 public boolean quickReject(RectF rect, EdgeType type) { 736 return native_quickReject(mNativeCanvas, rect); 737 } 738 739 /** 740 * Return true if the specified path, after being transformed by the 741 * current matrix, would lie completely outside of the current clip. Call 742 * this to check if an area you intend to draw into is clipped out (and 743 * therefore you can skip making the draw calls). Note: for speed it may 744 * return false even if the path itself might not intersect the clip 745 * (i.e. the bounds of the path intersects, but the path does not). 746 * 747 * @param path The path to compare with the current clip 748 * @param type {@link Canvas.EdgeType#AA} if the path should be considered antialiased, 749 * since that means it may affect a larger area (more pixels) than 750 * non-antialiased ({@link Canvas.EdgeType#BW}). 751 * @return true if the path (transformed by the canvas' matrix) 752 * does not intersect with the canvas' clip 753 */ quickReject(Path path, EdgeType type)754 public boolean quickReject(Path path, EdgeType type) { 755 return native_quickReject(mNativeCanvas, path.ni()); 756 } 757 758 /** 759 * Return true if the specified rectangle, after being transformed by the 760 * current matrix, would lie completely outside of the current clip. Call 761 * this to check if an area you intend to draw into is clipped out (and 762 * therefore you can skip making the draw calls). 763 * 764 * @param left The left side of the rectangle to compare with the 765 * current clip 766 * @param top The top of the rectangle to compare with the current 767 * clip 768 * @param right The right side of the rectangle to compare with the 769 * current clip 770 * @param bottom The bottom of the rectangle to compare with the 771 * current clip 772 * @param type {@link Canvas.EdgeType#AA} if the path should be considered antialiased, 773 * since that means it may affect a larger area (more pixels) than 774 * non-antialiased ({@link Canvas.EdgeType#BW}). 775 * @return true if the rect (transformed by the canvas' matrix) 776 * does not intersect with the canvas' clip 777 */ quickReject(float left, float top, float right, float bottom, EdgeType type)778 public boolean quickReject(float left, float top, float right, float bottom, 779 EdgeType type) { 780 return native_quickReject(mNativeCanvas, left, top, right, bottom); 781 } 782 783 /** 784 * Return the bounds of the current clip (in local coordinates) in the 785 * bounds parameter, and return true if it is non-empty. This can be useful 786 * in a way similar to quickReject, in that it tells you that drawing 787 * outside of these bounds will be clipped out. 788 * 789 * @param bounds Return the clip bounds here. If it is null, ignore it but 790 * still return true if the current clip is non-empty. 791 * @return true if the current clip is non-empty. 792 */ getClipBounds(Rect bounds)793 public boolean getClipBounds(Rect bounds) { 794 return native_getClipBounds(mNativeCanvas, bounds); 795 } 796 797 /** 798 * Retrieve the bounds of the current clip (in local coordinates). 799 * 800 * @return the clip bounds, or [0, 0, 0, 0] if the clip is empty. 801 */ getClipBounds()802 public final Rect getClipBounds() { 803 Rect r = new Rect(); 804 getClipBounds(r); 805 return r; 806 } 807 808 /** 809 * Fill the entire canvas' bitmap (restricted to the current clip) with the 810 * specified RGB color, using srcover porterduff mode. 811 * 812 * @param r red component (0..255) of the color to draw onto the canvas 813 * @param g green component (0..255) of the color to draw onto the canvas 814 * @param b blue component (0..255) of the color to draw onto the canvas 815 */ drawRGB(int r, int g, int b)816 public void drawRGB(int r, int g, int b) { 817 native_drawRGB(mNativeCanvas, r, g, b); 818 } 819 820 /** 821 * Fill the entire canvas' bitmap (restricted to the current clip) with the 822 * specified ARGB color, using srcover porterduff mode. 823 * 824 * @param a alpha component (0..255) of the color to draw onto the canvas 825 * @param r red component (0..255) of the color to draw onto the canvas 826 * @param g green component (0..255) of the color to draw onto the canvas 827 * @param b blue component (0..255) of the color to draw onto the canvas 828 */ drawARGB(int a, int r, int g, int b)829 public void drawARGB(int a, int r, int g, int b) { 830 native_drawARGB(mNativeCanvas, a, r, g, b); 831 } 832 833 /** 834 * Fill the entire canvas' bitmap (restricted to the current clip) with the 835 * specified color, using srcover porterduff mode. 836 * 837 * @param color the color to draw onto the canvas 838 */ drawColor(int color)839 public void drawColor(int color) { 840 native_drawColor(mNativeCanvas, color); 841 } 842 843 /** 844 * Fill the entire canvas' bitmap (restricted to the current clip) with the 845 * specified color and porter-duff xfermode. 846 * 847 * @param color the color to draw with 848 * @param mode the porter-duff mode to apply to the color 849 */ drawColor(int color, PorterDuff.Mode mode)850 public void drawColor(int color, PorterDuff.Mode mode) { 851 native_drawColor(mNativeCanvas, color, mode.nativeInt); 852 } 853 854 /** 855 * Fill the entire canvas' bitmap (restricted to the current clip) with 856 * the specified paint. This is equivalent (but faster) to drawing an 857 * infinitely large rectangle with the specified paint. 858 * 859 * @param paint The paint used to draw onto the canvas 860 */ drawPaint(Paint paint)861 public void drawPaint(Paint paint) { 862 native_drawPaint(mNativeCanvas, paint.mNativePaint); 863 } 864 865 /** 866 * Draw a series of points. Each point is centered at the coordinate 867 * specified by pts[], and its diameter is specified by the paint's stroke 868 * width (as transformed by the canvas' CTM), with special treatment for 869 * a stroke width of 0, which always draws exactly 1 pixel (or at most 4 870 * if antialiasing is enabled). The shape of the point is controlled by 871 * the paint's Cap type. The shape is a square, unless the cap type is 872 * Round, in which case the shape is a circle. 873 * 874 * @param pts Array of points to draw [x0 y0 x1 y1 x2 y2 ...] 875 * @param offset Number of values to skip before starting to draw. 876 * @param count The number of values to process, after skipping offset 877 * of them. Since one point uses two values, the number of 878 * "points" that are drawn is really (count >> 1). 879 * @param paint The paint used to draw the points 880 */ drawPoints(float[] pts, int offset, int count, Paint paint)881 public native void drawPoints(float[] pts, int offset, int count, Paint paint); 882 883 /** 884 * Helper for drawPoints() that assumes you want to draw the entire array 885 */ drawPoints(float[] pts, Paint paint)886 public void drawPoints(float[] pts, Paint paint) { 887 drawPoints(pts, 0, pts.length, paint); 888 } 889 890 /** 891 * Helper for drawPoints() for drawing a single point. 892 */ drawPoint(float x, float y, Paint paint)893 public native void drawPoint(float x, float y, Paint paint); 894 895 /** 896 * Draw a line segment with the specified start and stop x,y coordinates, 897 * using the specified paint. 898 * 899 * <p>Note that since a line is always "framed", the Style is ignored in the paint.</p> 900 * 901 * <p>Degenerate lines (length is 0) will not be drawn.</p> 902 * 903 * @param startX The x-coordinate of the start point of the line 904 * @param startY The y-coordinate of the start point of the line 905 * @param paint The paint used to draw the line 906 */ drawLine(float startX, float startY, float stopX, float stopY, Paint paint)907 public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { 908 native_drawLine(mNativeCanvas, startX, startY, stopX, stopY, paint.mNativePaint); 909 } 910 911 /** 912 * Draw a series of lines. Each line is taken from 4 consecutive values 913 * in the pts array. Thus to draw 1 line, the array must contain at least 4 914 * values. This is logically the same as drawing the array as follows: 915 * drawLine(pts[0], pts[1], pts[2], pts[3]) followed by 916 * drawLine(pts[4], pts[5], pts[6], pts[7]) and so on. 917 * 918 * @param pts Array of points to draw [x0 y0 x1 y1 x2 y2 ...] 919 * @param offset Number of values in the array to skip before drawing. 920 * @param count The number of values in the array to process, after 921 * skipping "offset" of them. Since each line uses 4 values, 922 * the number of "lines" that are drawn is really 923 * (count >> 2). 924 * @param paint The paint used to draw the points 925 */ drawLines(float[] pts, int offset, int count, Paint paint)926 public native void drawLines(float[] pts, int offset, int count, Paint paint); 927 drawLines(float[] pts, Paint paint)928 public void drawLines(float[] pts, Paint paint) { 929 drawLines(pts, 0, pts.length, paint); 930 } 931 932 /** 933 * Draw the specified Rect using the specified paint. The rectangle will 934 * be filled or framed based on the Style in the paint. 935 * 936 * @param rect The rect to be drawn 937 * @param paint The paint used to draw the rect 938 */ drawRect(RectF rect, Paint paint)939 public void drawRect(RectF rect, Paint paint) { 940 native_drawRect(mNativeCanvas, rect, paint.mNativePaint); 941 } 942 943 /** 944 * Draw the specified Rect using the specified Paint. The rectangle 945 * will be filled or framed based on the Style in the paint. 946 * 947 * @param r The rectangle to be drawn. 948 * @param paint The paint used to draw the rectangle 949 */ drawRect(Rect r, Paint paint)950 public void drawRect(Rect r, Paint paint) { 951 drawRect(r.left, r.top, r.right, r.bottom, paint); 952 } 953 954 955 /** 956 * Draw the specified Rect using the specified paint. The rectangle will 957 * be filled or framed based on the Style in the paint. 958 * 959 * @param left The left side of the rectangle to be drawn 960 * @param top The top side of the rectangle to be drawn 961 * @param right The right side of the rectangle to be drawn 962 * @param bottom The bottom side of the rectangle to be drawn 963 * @param paint The paint used to draw the rect 964 */ drawRect(float left, float top, float right, float bottom, Paint paint)965 public void drawRect(float left, float top, float right, float bottom, Paint paint) { 966 native_drawRect(mNativeCanvas, left, top, right, bottom, paint.mNativePaint); 967 } 968 969 /** 970 * Draw the specified oval using the specified paint. The oval will be 971 * filled or framed based on the Style in the paint. 972 * 973 * @param oval The rectangle bounds of the oval to be drawn 974 */ drawOval(RectF oval, Paint paint)975 public void drawOval(RectF oval, Paint paint) { 976 if (oval == null) { 977 throw new NullPointerException(); 978 } 979 native_drawOval(mNativeCanvas, oval, paint.mNativePaint); 980 } 981 982 /** 983 * Draw the specified circle using the specified paint. If radius is <= 0, 984 * then nothing will be drawn. The circle will be filled or framed based 985 * on the Style in the paint. 986 * 987 * @param cx The x-coordinate of the center of the cirle to be drawn 988 * @param cy The y-coordinate of the center of the cirle to be drawn 989 * @param radius The radius of the cirle to be drawn 990 * @param paint The paint used to draw the circle 991 */ drawCircle(float cx, float cy, float radius, Paint paint)992 public void drawCircle(float cx, float cy, float radius, Paint paint) { 993 native_drawCircle(mNativeCanvas, cx, cy, radius, paint.mNativePaint); 994 } 995 996 /** 997 * <p>Draw the specified arc, which will be scaled to fit inside the 998 * specified oval.</p> 999 * 1000 * <p>If the start angle is negative or >= 360, the start angle is treated 1001 * as start angle modulo 360.</p> 1002 * 1003 * <p>If the sweep angle is >= 360, then the oval is drawn 1004 * completely. Note that this differs slightly from SkPath::arcTo, which 1005 * treats the sweep angle modulo 360. If the sweep angle is negative, 1006 * the sweep angle is treated as sweep angle modulo 360</p> 1007 * 1008 * <p>The arc is drawn clockwise. An angle of 0 degrees correspond to the 1009 * geometric angle of 0 degrees (3 o'clock on a watch.)</p> 1010 * 1011 * @param oval The bounds of oval used to define the shape and size 1012 * of the arc 1013 * @param startAngle Starting angle (in degrees) where the arc begins 1014 * @param sweepAngle Sweep angle (in degrees) measured clockwise 1015 * @param useCenter If true, include the center of the oval in the arc, and 1016 close it if it is being stroked. This will draw a wedge 1017 * @param paint The paint used to draw the arc 1018 */ drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)1019 public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, 1020 Paint paint) { 1021 if (oval == null) { 1022 throw new NullPointerException(); 1023 } 1024 native_drawArc(mNativeCanvas, oval, startAngle, sweepAngle, 1025 useCenter, paint.mNativePaint); 1026 } 1027 1028 /** 1029 * Draw the specified round-rect using the specified paint. The roundrect 1030 * will be filled or framed based on the Style in the paint. 1031 * 1032 * @param rect The rectangular bounds of the roundRect to be drawn 1033 * @param rx The x-radius of the oval used to round the corners 1034 * @param ry The y-radius of the oval used to round the corners 1035 * @param paint The paint used to draw the roundRect 1036 */ drawRoundRect(RectF rect, float rx, float ry, Paint paint)1037 public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { 1038 if (rect == null) { 1039 throw new NullPointerException(); 1040 } 1041 native_drawRoundRect(mNativeCanvas, rect, rx, ry, 1042 paint.mNativePaint); 1043 } 1044 1045 /** 1046 * Draw the specified path using the specified paint. The path will be 1047 * filled or framed based on the Style in the paint. 1048 * 1049 * @param path The path to be drawn 1050 * @param paint The paint used to draw the path 1051 */ drawPath(Path path, Paint paint)1052 public void drawPath(Path path, Paint paint) { 1053 native_drawPath(mNativeCanvas, path.ni(), paint.mNativePaint); 1054 } 1055 throwIfRecycled(Bitmap bitmap)1056 private static void throwIfRecycled(Bitmap bitmap) { 1057 if (bitmap.isRecycled()) { 1058 throw new RuntimeException("Canvas: trying to use a recycled bitmap " + bitmap); 1059 } 1060 } 1061 1062 /** 1063 * Draws the specified bitmap as an N-patch (most often, a 9-patches.) 1064 * 1065 * Note: Only supported by hardware accelerated canvas at the moment. 1066 * 1067 * @param bitmap The bitmap to draw as an N-patch 1068 * @param chunks The patches information (matches the native struct Res_png_9patch) 1069 * @param dst The destination rectangle. 1070 * @param paint The paint to draw the bitmap with. may be null 1071 * 1072 * @hide 1073 */ drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint)1074 public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { 1075 } 1076 1077 /** 1078 * Draw the specified bitmap, with its top/left corner at (x,y), using 1079 * the specified paint, transformed by the current matrix. 1080 * 1081 * <p>Note: if the paint contains a maskfilter that generates a mask which 1082 * extends beyond the bitmap's original width/height (e.g. BlurMaskFilter), 1083 * then the bitmap will be drawn as if it were in a Shader with CLAMP mode. 1084 * Thus the color outside of the original width/height will be the edge 1085 * color replicated. 1086 * 1087 * <p>If the bitmap and canvas have different densities, this function 1088 * will take care of automatically scaling the bitmap to draw at the 1089 * same density as the canvas. 1090 * 1091 * @param bitmap The bitmap to be drawn 1092 * @param left The position of the left side of the bitmap being drawn 1093 * @param top The position of the top side of the bitmap being drawn 1094 * @param paint The paint used to draw the bitmap (may be null) 1095 */ drawBitmap(Bitmap bitmap, float left, float top, Paint paint)1096 public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { 1097 throwIfRecycled(bitmap); 1098 native_drawBitmap(mNativeCanvas, bitmap.ni(), left, top, 1099 paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity, bitmap.mDensity); 1100 } 1101 1102 /** 1103 * Draw the specified bitmap, scaling/translating automatically to fill 1104 * the destination rectangle. If the source rectangle is not null, it 1105 * specifies the subset of the bitmap to draw. 1106 * 1107 * <p>Note: if the paint contains a maskfilter that generates a mask which 1108 * extends beyond the bitmap's original width/height (e.g. BlurMaskFilter), 1109 * then the bitmap will be drawn as if it were in a Shader with CLAMP mode. 1110 * Thus the color outside of the original width/height will be the edge 1111 * color replicated. 1112 * 1113 * <p>This function <em>ignores the density associated with the bitmap</em>. 1114 * This is because the source and destination rectangle coordinate 1115 * spaces are in their respective densities, so must already have the 1116 * appropriate scaling factor applied. 1117 * 1118 * @param bitmap The bitmap to be drawn 1119 * @param src May be null. The subset of the bitmap to be drawn 1120 * @param dst The rectangle that the bitmap will be scaled/translated 1121 * to fit into 1122 * @param paint May be null. The paint used to draw the bitmap 1123 */ drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)1124 public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { 1125 if (dst == null) { 1126 throw new NullPointerException(); 1127 } 1128 throwIfRecycled(bitmap); 1129 native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst, 1130 paint != null ? paint.mNativePaint : 0, mScreenDensity, bitmap.mDensity); 1131 } 1132 1133 /** 1134 * Draw the specified bitmap, scaling/translating automatically to fill 1135 * the destination rectangle. If the source rectangle is not null, it 1136 * specifies the subset of the bitmap to draw. 1137 * 1138 * <p>Note: if the paint contains a maskfilter that generates a mask which 1139 * extends beyond the bitmap's original width/height (e.g. BlurMaskFilter), 1140 * then the bitmap will be drawn as if it were in a Shader with CLAMP mode. 1141 * Thus the color outside of the original width/height will be the edge 1142 * color replicated. 1143 * 1144 * <p>This function <em>ignores the density associated with the bitmap</em>. 1145 * This is because the source and destination rectangle coordinate 1146 * spaces are in their respective densities, so must already have the 1147 * appropriate scaling factor applied. 1148 * 1149 * @param bitmap The bitmap to be drawn 1150 * @param src May be null. The subset of the bitmap to be drawn 1151 * @param dst The rectangle that the bitmap will be scaled/translated 1152 * to fit into 1153 * @param paint May be null. The paint used to draw the bitmap 1154 */ drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)1155 public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { 1156 if (dst == null) { 1157 throw new NullPointerException(); 1158 } 1159 throwIfRecycled(bitmap); 1160 native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst, 1161 paint != null ? paint.mNativePaint : 0, mScreenDensity, bitmap.mDensity); 1162 } 1163 1164 /** 1165 * Treat the specified array of colors as a bitmap, and draw it. This gives 1166 * the same result as first creating a bitmap from the array, and then 1167 * drawing it, but this method avoids explicitly creating a bitmap object 1168 * which can be more efficient if the colors are changing often. 1169 * 1170 * @param colors Array of colors representing the pixels of the bitmap 1171 * @param offset Offset into the array of colors for the first pixel 1172 * @param stride The number of colors in the array between rows (must be 1173 * >= width or <= -width). 1174 * @param x The X coordinate for where to draw the bitmap 1175 * @param y The Y coordinate for where to draw the bitmap 1176 * @param width The width of the bitmap 1177 * @param height The height of the bitmap 1178 * @param hasAlpha True if the alpha channel of the colors contains valid 1179 * values. If false, the alpha byte is ignored (assumed to 1180 * be 0xFF for every pixel). 1181 * @param paint May be null. The paint used to draw the bitmap 1182 */ drawBitmap(int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, Paint paint)1183 public void drawBitmap(int[] colors, int offset, int stride, float x, float y, 1184 int width, int height, boolean hasAlpha, Paint paint) { 1185 // check for valid input 1186 if (width < 0) { 1187 throw new IllegalArgumentException("width must be >= 0"); 1188 } 1189 if (height < 0) { 1190 throw new IllegalArgumentException("height must be >= 0"); 1191 } 1192 if (Math.abs(stride) < width) { 1193 throw new IllegalArgumentException("abs(stride) must be >= width"); 1194 } 1195 int lastScanline = offset + (height - 1) * stride; 1196 int length = colors.length; 1197 if (offset < 0 || (offset + width > length) || lastScanline < 0 1198 || (lastScanline + width > length)) { 1199 throw new ArrayIndexOutOfBoundsException(); 1200 } 1201 // quick escape if there's nothing to draw 1202 if (width == 0 || height == 0) { 1203 return; 1204 } 1205 // punch down to native for the actual draw 1206 native_drawBitmap(mNativeCanvas, colors, offset, stride, x, y, width, height, hasAlpha, 1207 paint != null ? paint.mNativePaint : 0); 1208 } 1209 1210 /** Legacy version of drawBitmap(int[] colors, ...) that took ints for x,y 1211 */ drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, int height, boolean hasAlpha, Paint paint)1212 public void drawBitmap(int[] colors, int offset, int stride, int x, int y, 1213 int width, int height, boolean hasAlpha, Paint paint) { 1214 // call through to the common float version 1215 drawBitmap(colors, offset, stride, (float)x, (float)y, width, height, 1216 hasAlpha, paint); 1217 } 1218 1219 /** 1220 * Draw the bitmap using the specified matrix. 1221 * 1222 * @param bitmap The bitmap to draw 1223 * @param matrix The matrix used to transform the bitmap when it is drawn 1224 * @param paint May be null. The paint used to draw the bitmap 1225 */ drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)1226 public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { 1227 nativeDrawBitmapMatrix(mNativeCanvas, bitmap.ni(), matrix.ni(), 1228 paint != null ? paint.mNativePaint : 0); 1229 } 1230 1231 /** 1232 * @hide 1233 */ checkRange(int length, int offset, int count)1234 protected static void checkRange(int length, int offset, int count) { 1235 if ((offset | count) < 0 || offset + count > length) { 1236 throw new ArrayIndexOutOfBoundsException(); 1237 } 1238 } 1239 1240 /** 1241 * Draw the bitmap through the mesh, where mesh vertices are evenly 1242 * distributed across the bitmap. There are meshWidth+1 vertices across, and 1243 * meshHeight+1 vertices down. The verts array is accessed in row-major 1244 * order, so that the first meshWidth+1 vertices are distributed across the 1245 * top of the bitmap from left to right. A more general version of this 1246 * method is drawVertices(). 1247 * 1248 * @param bitmap The bitmap to draw using the mesh 1249 * @param meshWidth The number of columns in the mesh. Nothing is drawn if 1250 * this is 0 1251 * @param meshHeight The number of rows in the mesh. Nothing is drawn if 1252 * this is 0 1253 * @param verts Array of x,y pairs, specifying where the mesh should be 1254 * drawn. There must be at least 1255 * (meshWidth+1) * (meshHeight+1) * 2 + vertOffset values 1256 * in the array 1257 * @param vertOffset Number of verts elements to skip before drawing 1258 * @param colors May be null. Specifies a color at each vertex, which is 1259 * interpolated across the cell, and whose values are 1260 * multiplied by the corresponding bitmap colors. If not null, 1261 * there must be at least (meshWidth+1) * (meshHeight+1) + 1262 * colorOffset values in the array. 1263 * @param colorOffset Number of color elements to skip before drawing 1264 * @param paint May be null. The paint used to draw the bitmap 1265 */ drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)1266 public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, 1267 float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint) { 1268 if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) { 1269 throw new ArrayIndexOutOfBoundsException(); 1270 } 1271 if (meshWidth == 0 || meshHeight == 0) { 1272 return; 1273 } 1274 int count = (meshWidth + 1) * (meshHeight + 1); 1275 // we mul by 2 since we need two floats per vertex 1276 checkRange(verts.length, vertOffset, count * 2); 1277 if (colors != null) { 1278 // no mul by 2, since we need only 1 color per vertex 1279 checkRange(colors.length, colorOffset, count); 1280 } 1281 nativeDrawBitmapMesh(mNativeCanvas, bitmap.ni(), meshWidth, meshHeight, 1282 verts, vertOffset, colors, colorOffset, 1283 paint != null ? paint.mNativePaint : 0); 1284 } 1285 1286 public enum VertexMode { 1287 TRIANGLES(0), 1288 TRIANGLE_STRIP(1), 1289 TRIANGLE_FAN(2); 1290 VertexMode(int nativeInt)1291 VertexMode(int nativeInt) { 1292 this.nativeInt = nativeInt; 1293 } 1294 1295 /** 1296 * @hide 1297 */ 1298 public final int nativeInt; 1299 } 1300 1301 /** 1302 * Draw the array of vertices, interpreted as triangles (based on mode). The 1303 * verts array is required, and specifies the x,y pairs for each vertex. If 1304 * texs is non-null, then it is used to specify the coordinate in shader 1305 * coordinates to use at each vertex (the paint must have a shader in this 1306 * case). If there is no texs array, but there is a color array, then each 1307 * color is interpolated across its corresponding triangle in a gradient. If 1308 * both texs and colors arrays are present, then they behave as before, but 1309 * the resulting color at each pixels is the result of multiplying the 1310 * colors from the shader and the color-gradient together. The indices array 1311 * is optional, but if it is present, then it is used to specify the index 1312 * of each triangle, rather than just walking through the arrays in order. 1313 * 1314 * @param mode How to interpret the array of vertices 1315 * @param vertexCount The number of values in the vertices array (and 1316 * corresponding texs and colors arrays if non-null). Each logical 1317 * vertex is two values (x, y), vertexCount must be a multiple of 2. 1318 * @param verts Array of vertices for the mesh 1319 * @param vertOffset Number of values in the verts to skip before drawing. 1320 * @param texs May be null. If not null, specifies the coordinates to sample 1321 * into the current shader (e.g. bitmap tile or gradient) 1322 * @param texOffset Number of values in texs to skip before drawing. 1323 * @param colors May be null. If not null, specifies a color for each 1324 * vertex, to be interpolated across the triangle. 1325 * @param colorOffset Number of values in colors to skip before drawing. 1326 * @param indices If not null, array of indices to reference into the 1327 * vertex (texs, colors) array. 1328 * @param indexCount number of entries in the indices array (if not null). 1329 * @param paint Specifies the shader to use if the texs array is non-null. 1330 */ drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, int indexOffset, int indexCount, Paint paint)1331 public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, 1332 float[] texs, int texOffset, int[] colors, int colorOffset, 1333 short[] indices, int indexOffset, int indexCount, Paint paint) { 1334 checkRange(verts.length, vertOffset, vertexCount); 1335 if (texs != null) { 1336 checkRange(texs.length, texOffset, vertexCount); 1337 } 1338 if (colors != null) { 1339 checkRange(colors.length, colorOffset, vertexCount / 2); 1340 } 1341 if (indices != null) { 1342 checkRange(indices.length, indexOffset, indexCount); 1343 } 1344 nativeDrawVertices(mNativeCanvas, mode.nativeInt, vertexCount, verts, 1345 vertOffset, texs, texOffset, colors, colorOffset, 1346 indices, indexOffset, indexCount, paint.mNativePaint); 1347 } 1348 1349 /** 1350 * Draw the text, with origin at (x,y), using the specified paint. The 1351 * origin is interpreted based on the Align setting in the paint. 1352 * 1353 * @param text The text to be drawn 1354 * @param x The x-coordinate of the origin of the text being drawn 1355 * @param y The y-coordinate of the origin of the text being drawn 1356 * @param paint The paint used for the text (e.g. color, size, style) 1357 */ drawText(char[] text, int index, int count, float x, float y, Paint paint)1358 public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { 1359 if ((index | count | (index + count) | 1360 (text.length - index - count)) < 0) { 1361 throw new IndexOutOfBoundsException(); 1362 } 1363 native_drawText(mNativeCanvas, text, index, count, x, y, paint.mBidiFlags, 1364 paint.mNativePaint); 1365 } 1366 1367 /** 1368 * Draw the text, with origin at (x,y), using the specified paint. The 1369 * origin is interpreted based on the Align setting in the paint. 1370 * 1371 * @param text The text to be drawn 1372 * @param x The x-coordinate of the origin of the text being drawn 1373 * @param y The y-coordinate of the origin of the text being drawn 1374 * @param paint The paint used for the text (e.g. color, size, style) 1375 */ drawText(String text, float x, float y, Paint paint)1376 public void drawText(String text, float x, float y, Paint paint) { 1377 native_drawText(mNativeCanvas, text, 0, text.length(), x, y, paint.mBidiFlags, 1378 paint.mNativePaint); 1379 } 1380 1381 /** 1382 * Draw the text, with origin at (x,y), using the specified paint. 1383 * The origin is interpreted based on the Align setting in the paint. 1384 * 1385 * @param text The text to be drawn 1386 * @param start The index of the first character in text to draw 1387 * @param end (end - 1) is the index of the last character in text to draw 1388 * @param x The x-coordinate of the origin of the text being drawn 1389 * @param y The y-coordinate of the origin of the text being drawn 1390 * @param paint The paint used for the text (e.g. color, size, style) 1391 */ drawText(String text, int start, int end, float x, float y, Paint paint)1392 public void drawText(String text, int start, int end, float x, float y, Paint paint) { 1393 if ((start | end | (end - start) | (text.length() - end)) < 0) { 1394 throw new IndexOutOfBoundsException(); 1395 } 1396 native_drawText(mNativeCanvas, text, start, end, x, y, paint.mBidiFlags, 1397 paint.mNativePaint); 1398 } 1399 1400 /** 1401 * Draw the specified range of text, specified by start/end, with its 1402 * origin at (x,y), in the specified Paint. The origin is interpreted 1403 * based on the Align setting in the Paint. 1404 * 1405 * @param text The text to be drawn 1406 * @param start The index of the first character in text to draw 1407 * @param end (end - 1) is the index of the last character in text 1408 * to draw 1409 * @param x The x-coordinate of origin for where to draw the text 1410 * @param y The y-coordinate of origin for where to draw the text 1411 * @param paint The paint used for the text (e.g. color, size, style) 1412 */ drawText(CharSequence text, int start, int end, float x, float y, Paint paint)1413 public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { 1414 if (text instanceof String || text instanceof SpannedString || 1415 text instanceof SpannableString) { 1416 native_drawText(mNativeCanvas, text.toString(), start, end, x, y, 1417 paint.mBidiFlags, paint.mNativePaint); 1418 } else if (text instanceof GraphicsOperations) { 1419 ((GraphicsOperations) text).drawText(this, start, end, x, y, 1420 paint); 1421 } else { 1422 char[] buf = TemporaryBuffer.obtain(end - start); 1423 TextUtils.getChars(text, start, end, buf, 0); 1424 native_drawText(mNativeCanvas, buf, 0, end - start, x, y, 1425 paint.mBidiFlags, paint.mNativePaint); 1426 TemporaryBuffer.recycle(buf); 1427 } 1428 } 1429 1430 /** 1431 * Render a run of all LTR or all RTL text, with shaping. This does not run 1432 * bidi on the provided text, but renders it as a uniform right-to-left or 1433 * left-to-right run, as indicated by dir. Alignment of the text is as 1434 * determined by the Paint's TextAlign value. 1435 * 1436 * @param text the text to render 1437 * @param index the start of the text to render 1438 * @param count the count of chars to render 1439 * @param contextIndex the start of the context for shaping. Must be 1440 * no greater than index. 1441 * @param contextCount the number of characters in the context for shaping. 1442 * ContexIndex + contextCount must be no less than index 1443 * + count. 1444 * @param x the x position at which to draw the text 1445 * @param y the y position at which to draw the text 1446 * @param dir the run direction, either {@link #DIRECTION_LTR} or 1447 * {@link #DIRECTION_RTL}. 1448 * @param paint the paint 1449 * @hide 1450 */ drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int dir, Paint paint)1451 public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, 1452 float x, float y, int dir, Paint paint) { 1453 1454 if (text == null) { 1455 throw new NullPointerException("text is null"); 1456 } 1457 if (paint == null) { 1458 throw new NullPointerException("paint is null"); 1459 } 1460 if ((index | count | text.length - index - count) < 0) { 1461 throw new IndexOutOfBoundsException(); 1462 } 1463 if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { 1464 throw new IllegalArgumentException("unknown dir: " + dir); 1465 } 1466 1467 native_drawTextRun(mNativeCanvas, text, index, count, 1468 contextIndex, contextCount, x, y, dir, paint.mNativePaint); 1469 } 1470 1471 /** 1472 * Render a run of all LTR or all RTL text, with shaping. This does not run 1473 * bidi on the provided text, but renders it as a uniform right-to-left or 1474 * left-to-right run, as indicated by dir. Alignment of the text is as 1475 * determined by the Paint's TextAlign value. 1476 * 1477 * @param text the text to render 1478 * @param start the start of the text to render. Data before this position 1479 * can be used for shaping context. 1480 * @param end the end of the text to render. Data at or after this 1481 * position can be used for shaping context. 1482 * @param x the x position at which to draw the text 1483 * @param y the y position at which to draw the text 1484 * @param dir the run direction, either 0 for LTR or 1 for RTL. 1485 * @param paint the paint 1486 * @hide 1487 */ drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, int dir, Paint paint)1488 public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, 1489 float x, float y, int dir, Paint paint) { 1490 1491 if (text == null) { 1492 throw new NullPointerException("text is null"); 1493 } 1494 if (paint == null) { 1495 throw new NullPointerException("paint is null"); 1496 } 1497 if ((start | end | end - start | text.length() - end) < 0) { 1498 throw new IndexOutOfBoundsException(); 1499 } 1500 1501 int flags = dir == 0 ? 0 : 1; 1502 1503 if (text instanceof String || text instanceof SpannedString || 1504 text instanceof SpannableString) { 1505 native_drawTextRun(mNativeCanvas, text.toString(), start, end, 1506 contextStart, contextEnd, x, y, flags, paint.mNativePaint); 1507 } else if (text instanceof GraphicsOperations) { 1508 ((GraphicsOperations) text).drawTextRun(this, start, end, 1509 contextStart, contextEnd, x, y, flags, paint); 1510 } else { 1511 int contextLen = contextEnd - contextStart; 1512 int len = end - start; 1513 char[] buf = TemporaryBuffer.obtain(contextLen); 1514 TextUtils.getChars(text, contextStart, contextEnd, buf, 0); 1515 native_drawTextRun(mNativeCanvas, buf, start - contextStart, len, 1516 0, contextLen, x, y, flags, paint.mNativePaint); 1517 TemporaryBuffer.recycle(buf); 1518 } 1519 } 1520 1521 /** 1522 * Draw the text in the array, with each character's origin specified by 1523 * the pos array. 1524 * 1525 * This method does not support glyph composition and decomposition and 1526 * should therefore not be used to render complex scripts. 1527 * 1528 * @param text The text to be drawn 1529 * @param index The index of the first character to draw 1530 * @param count The number of characters to draw, starting from index. 1531 * @param pos Array of [x,y] positions, used to position each 1532 * character 1533 * @param paint The paint used for the text (e.g. color, size, style) 1534 */ 1535 @Deprecated drawPosText(char[] text, int index, int count, float[] pos, Paint paint)1536 public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { 1537 if (index < 0 || index + count > text.length || count*2 > pos.length) { 1538 throw new IndexOutOfBoundsException(); 1539 } 1540 native_drawPosText(mNativeCanvas, text, index, count, pos, 1541 paint.mNativePaint); 1542 } 1543 1544 /** 1545 * Draw the text in the array, with each character's origin specified by 1546 * the pos array. 1547 * 1548 * This method does not support glyph composition and decomposition and 1549 * should therefore not be used to render complex scripts. 1550 * 1551 * @param text The text to be drawn 1552 * @param pos Array of [x,y] positions, used to position each character 1553 * @param paint The paint used for the text (e.g. color, size, style) 1554 */ 1555 @Deprecated drawPosText(String text, float[] pos, Paint paint)1556 public void drawPosText(String text, float[] pos, Paint paint) { 1557 if (text.length()*2 > pos.length) { 1558 throw new ArrayIndexOutOfBoundsException(); 1559 } 1560 native_drawPosText(mNativeCanvas, text, pos, paint.mNativePaint); 1561 } 1562 1563 /** 1564 * Draw the text, with origin at (x,y), using the specified paint, along 1565 * the specified path. The paint's Align setting determins where along the 1566 * path to start the text. 1567 * 1568 * @param text The text to be drawn 1569 * @param path The path the text should follow for its baseline 1570 * @param hOffset The distance along the path to add to the text's 1571 * starting position 1572 * @param vOffset The distance above(-) or below(+) the path to position 1573 * the text 1574 * @param paint The paint used for the text (e.g. color, size, style) 1575 */ drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)1576 public void drawTextOnPath(char[] text, int index, int count, Path path, 1577 float hOffset, float vOffset, Paint paint) { 1578 if (index < 0 || index + count > text.length) { 1579 throw new ArrayIndexOutOfBoundsException(); 1580 } 1581 native_drawTextOnPath(mNativeCanvas, text, index, count, 1582 path.ni(), hOffset, vOffset, 1583 paint.mBidiFlags, paint.mNativePaint); 1584 } 1585 1586 /** 1587 * Draw the text, with origin at (x,y), using the specified paint, along 1588 * the specified path. The paint's Align setting determins where along the 1589 * path to start the text. 1590 * 1591 * @param text The text to be drawn 1592 * @param path The path the text should follow for its baseline 1593 * @param hOffset The distance along the path to add to the text's 1594 * starting position 1595 * @param vOffset The distance above(-) or below(+) the path to position 1596 * the text 1597 * @param paint The paint used for the text (e.g. color, size, style) 1598 */ drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)1599 public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { 1600 if (text.length() > 0) { 1601 native_drawTextOnPath(mNativeCanvas, text, path.ni(), hOffset, vOffset, 1602 paint.mBidiFlags, paint.mNativePaint); 1603 } 1604 } 1605 1606 /** 1607 * Save the canvas state, draw the picture, and restore the canvas state. 1608 * This differs from picture.draw(canvas), which does not perform any 1609 * save/restore. 1610 * 1611 * <p> 1612 * <strong>Note:</strong> This forces the picture to internally call 1613 * {@link Picture#endRecording} in order to prepare for playback. 1614 * 1615 * @param picture The picture to be drawn 1616 */ drawPicture(Picture picture)1617 public void drawPicture(Picture picture) { 1618 picture.endRecording(); 1619 native_drawPicture(mNativeCanvas, picture.ni()); 1620 } 1621 1622 /** 1623 * Draw the picture, stretched to fit into the dst rectangle. 1624 */ drawPicture(Picture picture, RectF dst)1625 public void drawPicture(Picture picture, RectF dst) { 1626 save(); 1627 translate(dst.left, dst.top); 1628 if (picture.getWidth() > 0 && picture.getHeight() > 0) { 1629 scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight()); 1630 } 1631 drawPicture(picture); 1632 restore(); 1633 } 1634 1635 /** 1636 * Draw the picture, stretched to fit into the dst rectangle. 1637 */ drawPicture(Picture picture, Rect dst)1638 public void drawPicture(Picture picture, Rect dst) { 1639 save(); 1640 translate(dst.left, dst.top); 1641 if (picture.getWidth() > 0 && picture.getHeight() > 0) { 1642 scale((float) dst.width() / picture.getWidth(), 1643 (float) dst.height() / picture.getHeight()); 1644 } 1645 drawPicture(picture); 1646 restore(); 1647 } 1648 1649 /** 1650 * Free up as much memory as possible from private caches (e.g. fonts, images) 1651 * 1652 * @hide 1653 */ freeCaches()1654 public static native void freeCaches(); 1655 1656 /** 1657 * Free up text layout caches 1658 * 1659 * @hide 1660 */ freeTextLayoutCaches()1661 public static native void freeTextLayoutCaches(); 1662 initRaster(int nativeBitmapOrZero)1663 private static native int initRaster(int nativeBitmapOrZero); copyNativeCanvasState(int srcCanvas, int dstCanvas)1664 private static native void copyNativeCanvasState(int srcCanvas, int dstCanvas); native_saveLayer(int nativeCanvas, RectF bounds, int paint, int layerFlags)1665 private static native int native_saveLayer(int nativeCanvas, RectF bounds, 1666 int paint, int layerFlags); native_saveLayer(int nativeCanvas, float l, float t, float r, float b, int paint, int layerFlags)1667 private static native int native_saveLayer(int nativeCanvas, float l, 1668 float t, float r, float b, 1669 int paint, int layerFlags); native_saveLayerAlpha(int nativeCanvas, RectF bounds, int alpha, int layerFlags)1670 private static native int native_saveLayerAlpha(int nativeCanvas, 1671 RectF bounds, int alpha, 1672 int layerFlags); native_saveLayerAlpha(int nativeCanvas, float l, float t, float r, float b, int alpha, int layerFlags)1673 private static native int native_saveLayerAlpha(int nativeCanvas, float l, 1674 float t, float r, float b, 1675 int alpha, int layerFlags); 1676 native_concat(int nCanvas, int nMatrix)1677 private static native void native_concat(int nCanvas, int nMatrix); native_setMatrix(int nCanvas, int nMatrix)1678 private static native void native_setMatrix(int nCanvas, int nMatrix); native_clipRect(int nCanvas, float left, float top, float right, float bottom, int regionOp)1679 private static native boolean native_clipRect(int nCanvas, 1680 float left, float top, 1681 float right, float bottom, 1682 int regionOp); native_clipPath(int nativeCanvas, int nativePath, int regionOp)1683 private static native boolean native_clipPath(int nativeCanvas, 1684 int nativePath, 1685 int regionOp); native_clipRegion(int nativeCanvas, int nativeRegion, int regionOp)1686 private static native boolean native_clipRegion(int nativeCanvas, 1687 int nativeRegion, 1688 int regionOp); nativeSetDrawFilter(int nativeCanvas, int nativeFilter)1689 private static native void nativeSetDrawFilter(int nativeCanvas, 1690 int nativeFilter); native_getClipBounds(int nativeCanvas, Rect bounds)1691 private static native boolean native_getClipBounds(int nativeCanvas, 1692 Rect bounds); native_getCTM(int canvas, int matrix)1693 private static native void native_getCTM(int canvas, int matrix); native_quickReject(int nativeCanvas, RectF rect)1694 private static native boolean native_quickReject(int nativeCanvas, 1695 RectF rect); native_quickReject(int nativeCanvas, int path)1696 private static native boolean native_quickReject(int nativeCanvas, 1697 int path); native_quickReject(int nativeCanvas, float left, float top, float right, float bottom)1698 private static native boolean native_quickReject(int nativeCanvas, 1699 float left, float top, 1700 float right, float bottom); native_drawRGB(int nativeCanvas, int r, int g, int b)1701 private static native void native_drawRGB(int nativeCanvas, int r, int g, 1702 int b); native_drawARGB(int nativeCanvas, int a, int r, int g, int b)1703 private static native void native_drawARGB(int nativeCanvas, int a, int r, 1704 int g, int b); native_drawColor(int nativeCanvas, int color)1705 private static native void native_drawColor(int nativeCanvas, int color); native_drawColor(int nativeCanvas, int color, int mode)1706 private static native void native_drawColor(int nativeCanvas, int color, 1707 int mode); native_drawPaint(int nativeCanvas, int paint)1708 private static native void native_drawPaint(int nativeCanvas, int paint); native_drawLine(int nativeCanvas, float startX, float startY, float stopX, float stopY, int paint)1709 private static native void native_drawLine(int nativeCanvas, float startX, 1710 float startY, float stopX, 1711 float stopY, int paint); native_drawRect(int nativeCanvas, RectF rect, int paint)1712 private static native void native_drawRect(int nativeCanvas, RectF rect, 1713 int paint); native_drawRect(int nativeCanvas, float left, float top, float right, float bottom, int paint)1714 private static native void native_drawRect(int nativeCanvas, float left, 1715 float top, float right, 1716 float bottom, int paint); native_drawOval(int nativeCanvas, RectF oval, int paint)1717 private static native void native_drawOval(int nativeCanvas, RectF oval, 1718 int paint); native_drawCircle(int nativeCanvas, float cx, float cy, float radius, int paint)1719 private static native void native_drawCircle(int nativeCanvas, float cx, 1720 float cy, float radius, 1721 int paint); native_drawArc(int nativeCanvas, RectF oval, float startAngle, float sweep, boolean useCenter, int paint)1722 private static native void native_drawArc(int nativeCanvas, RectF oval, 1723 float startAngle, float sweep, 1724 boolean useCenter, int paint); native_drawRoundRect(int nativeCanvas, RectF rect, float rx, float ry, int paint)1725 private static native void native_drawRoundRect(int nativeCanvas, 1726 RectF rect, float rx, 1727 float ry, int paint); native_drawPath(int nativeCanvas, int path, int paint)1728 private static native void native_drawPath(int nativeCanvas, int path, 1729 int paint); native_drawBitmap(int nativeCanvas, int bitmap, float left, float top, int nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity)1730 private native void native_drawBitmap(int nativeCanvas, int bitmap, 1731 float left, float top, 1732 int nativePaintOrZero, 1733 int canvasDensity, 1734 int screenDensity, 1735 int bitmapDensity); native_drawBitmap(int nativeCanvas, int bitmap, Rect src, RectF dst, int nativePaintOrZero, int screenDensity, int bitmapDensity)1736 private native void native_drawBitmap(int nativeCanvas, int bitmap, 1737 Rect src, RectF dst, 1738 int nativePaintOrZero, 1739 int screenDensity, 1740 int bitmapDensity); native_drawBitmap(int nativeCanvas, int bitmap, Rect src, Rect dst, int nativePaintOrZero, int screenDensity, int bitmapDensity)1741 private static native void native_drawBitmap(int nativeCanvas, int bitmap, 1742 Rect src, Rect dst, 1743 int nativePaintOrZero, 1744 int screenDensity, 1745 int bitmapDensity); native_drawBitmap(int nativeCanvas, int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, int nativePaintOrZero)1746 private static native void native_drawBitmap(int nativeCanvas, int[] colors, 1747 int offset, int stride, float x, 1748 float y, int width, int height, 1749 boolean hasAlpha, 1750 int nativePaintOrZero); nativeDrawBitmapMatrix(int nCanvas, int nBitmap, int nMatrix, int nPaint)1751 private static native void nativeDrawBitmapMatrix(int nCanvas, int nBitmap, 1752 int nMatrix, int nPaint); nativeDrawBitmapMesh(int nCanvas, int nBitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, int nPaint)1753 private static native void nativeDrawBitmapMesh(int nCanvas, int nBitmap, 1754 int meshWidth, int meshHeight, 1755 float[] verts, int vertOffset, 1756 int[] colors, int colorOffset, int nPaint); nativeDrawVertices(int nCanvas, int mode, int n, float[] verts, int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, int indexOffset, int indexCount, int nPaint)1757 private static native void nativeDrawVertices(int nCanvas, int mode, int n, 1758 float[] verts, int vertOffset, float[] texs, int texOffset, 1759 int[] colors, int colorOffset, short[] indices, 1760 int indexOffset, int indexCount, int nPaint); 1761 native_drawText(int nativeCanvas, char[] text, int index, int count, float x, float y, int flags, int paint)1762 private static native void native_drawText(int nativeCanvas, char[] text, 1763 int index, int count, float x, 1764 float y, int flags, int paint); native_drawText(int nativeCanvas, String text, int start, int end, float x, float y, int flags, int paint)1765 private static native void native_drawText(int nativeCanvas, String text, 1766 int start, int end, float x, 1767 float y, int flags, int paint); 1768 native_drawTextRun(int nativeCanvas, String text, int start, int end, int contextStart, int contextEnd, float x, float y, int flags, int paint)1769 private static native void native_drawTextRun(int nativeCanvas, String text, 1770 int start, int end, int contextStart, int contextEnd, 1771 float x, float y, int flags, int paint); 1772 native_drawTextRun(int nativeCanvas, char[] text, int start, int count, int contextStart, int contextCount, float x, float y, int flags, int paint)1773 private static native void native_drawTextRun(int nativeCanvas, char[] text, 1774 int start, int count, int contextStart, int contextCount, 1775 float x, float y, int flags, int paint); 1776 native_drawPosText(int nativeCanvas, char[] text, int index, int count, float[] pos, int paint)1777 private static native void native_drawPosText(int nativeCanvas, 1778 char[] text, int index, 1779 int count, float[] pos, 1780 int paint); native_drawPosText(int nativeCanvas, String text, float[] pos, int paint)1781 private static native void native_drawPosText(int nativeCanvas, 1782 String text, float[] pos, 1783 int paint); native_drawTextOnPath(int nativeCanvas, char[] text, int index, int count, int path, float hOffset, float vOffset, int bidiFlags, int paint)1784 private static native void native_drawTextOnPath(int nativeCanvas, 1785 char[] text, int index, 1786 int count, int path, 1787 float hOffset, 1788 float vOffset, int bidiFlags, 1789 int paint); native_drawTextOnPath(int nativeCanvas, String text, int path, float hOffset, float vOffset, int flags, int paint)1790 private static native void native_drawTextOnPath(int nativeCanvas, 1791 String text, int path, 1792 float hOffset, 1793 float vOffset, 1794 int flags, int paint); native_drawPicture(int nativeCanvas, int nativePicture)1795 private static native void native_drawPicture(int nativeCanvas, 1796 int nativePicture); finalizer(int nativeCanvas)1797 private static native void finalizer(int nativeCanvas); 1798 } 1799