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