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