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