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