Canvas.java revision 3891f3ad598561d5a82c07795e1fee7f1d3612d1
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1980756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt;
20ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabreseimport android.annotation.IntDef;
21ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabreseimport android.annotation.NonNull;
22ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabreseimport android.annotation.Nullable;
23b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbyeimport android.annotation.Size;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.GraphicsOperations;
25f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Feltimport android.text.SpannableString;
26f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Feltimport android.text.SpannedString;
27f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Feltimport android.text.TextUtils;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabreseimport java.lang.annotation.Retention;
30ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabreseimport java.lang.annotation.RetentionPolicy;
31ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese
32091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craikimport javax.microedition.khronos.opengles.GL;
33091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The Canvas class holds the "draw" calls. To draw something, you need
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4 basic components: A Bitmap to hold the pixels, a Canvas to host
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect,
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Path, text, Bitmap), and a paint (to describe the colors and styles for the
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawing).
4061fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez *
4161fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <div class="special reference">
4261fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <h3>Developer Guides</h3>
4361fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <p>For more information about how to use Canvas, read the
4461fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html">
4561fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * Canvas and Drawables</a> developer guide.</p></div>
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Canvas {
483891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik    /** @hide */
493891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik    public static boolean sCompatibilityRestore = false;
50ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov
518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    /**
528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson     * Should only be assigned in constructors (or setBitmap if software canvas),
538dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson     * freed in finalizer.
548dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson     * @hide
558dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson     */
568dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    protected long mNativeCanvasWrapper;
57c677675e9c465dc1de21ecf2e0421835c7eb55b4Florin Malita
58ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov    /** @hide */
595c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita    public long getNativeCanvasWrapper() {
605c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return mNativeCanvasWrapper;
61c677675e9c465dc1de21ecf2e0421835c7eb55b4Florin Malita    }
62ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov
63a753f4c6cb8558795e673df1896532cd148781e2Chris Craik    /** @hide */
64a753f4c6cb8558795e673df1896532cd148781e2Chris Craik    public boolean isRecordingFor(Object o) { return false; }
65a753f4c6cb8558795e673df1896532cd148781e2Chris Craik
66e0aa84b7dc087e999e20055dcc04cb6a48d5bd62Romain Guy    // may be null
67e0aa84b7dc087e999e20055dcc04cb6a48d5bd62Romain Guy    private Bitmap mBitmap;
68ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // optional field set by the caller
70ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    private DrawFilter mDrawFilter;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
72ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
73ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     * @hide
74ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
75ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    protected int mDensity = Bitmap.DENSITY_NONE;
760d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn
77ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
78ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     * Used to determine when compatibility scaling is in effect.
79051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
80ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     * @hide
81ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
82ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    protected int mScreenDensity = Bitmap.DENSITY_NONE;
83051910b9f998030dacb8a0722588cc715813fde1Raph Levien
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Used by native code
85f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy    @SuppressWarnings("UnusedDeclaration")
86e0aa84b7dc087e999e20055dcc04cb6a48d5bd62Romain Guy    private int mSurfaceFormat;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
88da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    /**
89da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio     * Flag for drawTextRun indicating left-to-right run direction.
90da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio     * @hide
91da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio     */
92da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    public static final int DIRECTION_LTR = 0;
93051910b9f998030dacb8a0722588cc715813fde1Raph Levien
94da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    /**
95da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio     * Flag for drawTextRun indicating right-to-left run direction.
96da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio     * @hide
97da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio     */
98da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    public static final int DIRECTION_RTL = 1;
99da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio
100f61970fc79e9c5cf340fa942597628242361864aRomain Guy    // Maximum bitmap size as defined in Skia's native code
101f61970fc79e9c5cf340fa942597628242361864aRomain Guy    // (see SkCanvas.cpp, SkDraw.cpp)
102f61970fc79e9c5cf340fa942597628242361864aRomain Guy    private static final int MAXMIMUM_BITMAP_SIZE = 32766;
103f61970fc79e9c5cf340fa942597628242361864aRomain Guy
1044a317db43d2bbc992284dd1f651751f13734d017Romain Guy    // This field is used to finalize the native Canvas properly
105e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy    private final CanvasFinalizer mFinalizer;
106e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
107ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov    private static final class CanvasFinalizer {
1085c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        private long mNativeCanvasWrapper;
109e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
11036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        public CanvasFinalizer(long nativeCanvas) {
1115c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            mNativeCanvasWrapper = nativeCanvas;
112e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        }
113e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
114e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        @Override
115e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        protected void finalize() throws Throwable {
1163b703f2d11f20efaa953ad31d6c97fe3561efb03Romain Guy            try {
117ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov                dispose();
1183b703f2d11f20efaa953ad31d6c97fe3561efb03Romain Guy            } finally {
1193b703f2d11f20efaa953ad31d6c97fe3561efb03Romain Guy                super.finalize();
120e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            }
121e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        }
122ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov
123ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov        public void dispose() {
1245c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            if (mNativeCanvasWrapper != 0) {
1255c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita                finalizer(mNativeCanvasWrapper);
1265c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita                mNativeCanvasWrapper = 0;
127ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov            }
128ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov        }
129e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy    }
130e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
131f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    /**
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Construct an empty raster canvas. Use setBitmap() to specify a bitmap to
13396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * draw into.  The initial target density is {@link Bitmap#DENSITY_NONE};
13496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * this will typically be replaced when a target bitmap is set for the
13596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * canvas.
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Canvas() {
138003123004f7b23b3dc472d5c40b8c1a16df37a54Romain Guy        if (!isHardwareAccelerated()) {
139003123004f7b23b3dc472d5c40b8c1a16df37a54Romain Guy            // 0 means no native bitmap
1405c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            mNativeCanvasWrapper = initRaster(0);
1415c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
142003123004f7b23b3dc472d5c40b8c1a16df37a54Romain Guy        } else {
143003123004f7b23b3dc472d5c40b8c1a16df37a54Romain Guy            mFinalizer = null;
144003123004f7b23b3dc472d5c40b8c1a16df37a54Romain Guy        }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Construct a canvas with the specified bitmap to draw into. The bitmap
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * must be mutable.
150051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
15196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>The initial target density of the canvas is the same as the given
15296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * bitmap's density.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap Specifies a mutable bitmap for the canvas to draw into.
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
156ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public Canvas(@NonNull Bitmap bitmap) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!bitmap.isMutable()) {
158f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy            throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1601abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
161f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        mNativeCanvasWrapper = initRaster(bitmap.getSkBitmap());
1625c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBitmap = bitmap;
16496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        mDensity = bitmap.mDensity;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
166ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov
167ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov    /** @hide */
16836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    public Canvas(long nativeCanvas) {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nativeCanvas == 0) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException();
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1728872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        mNativeCanvasWrapper = nativeCanvas;
1735c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
17496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        mDensity = Bitmap.getDefaultDensity();
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
176163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
178091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik     * Returns null.
179c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     *
180091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik     * @deprecated This method is not supported and should not be invoked.
181c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     *
182091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik     * @hide
183091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik     */
184091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik    @Deprecated
185091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik    protected GL getGL() {
186091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik        return null;
187091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik    }
188091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik
189091ddb1374e3bcdac129c1df5ef2555cf5c2183eChris Craik    /**
1902d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy     * Indicates whether this Canvas uses hardware acceleration.
191051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
1922d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy     * Note that this method does not define what type of hardware acceleration
1932d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy     * may or may not be used.
194051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
1952d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy     * @return True if drawing operations are hardware accelerated,
1962d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy     *         false otherwise.
1972d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy     */
1982d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy    public boolean isHardwareAccelerated() {
199163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return false;
200caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed    }
201163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
203051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * Specify a bitmap for the canvas to draw into. All canvas state such as
2043bd9a6dc6b30ed0ce40ca9087ca0f4b1ca789100Derek Sollenberger     * layers, filters, and the save/restore stack are reset with the exception
2053bd9a6dc6b30ed0ce40ca9087ca0f4b1ca789100Derek Sollenberger     * of the current matrix and clip stack. Additionally, as a side-effect
2063bd9a6dc6b30ed0ce40ca9087ca0f4b1ca789100Derek Sollenberger     * the canvas' target density is updated to match that of the bitmap.
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap Specifies a mutable bitmap for the canvas to draw into.
20996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @see #setDensity(int)
21096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @see #getDensity()
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
212ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void setBitmap(@Nullable Bitmap bitmap) {
213163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        if (isHardwareAccelerated()) {
21496890564bdbd2f2a41dfc323fc8b3938fb335639Chris Craik            throw new RuntimeException("Can't set a bitmap device on a HW accelerated canvas");
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
217fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger        if (bitmap == null) {
2185c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            native_setBitmap(mNativeCanvasWrapper, 0, false);
219fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger            mDensity = Bitmap.DENSITY_NONE;
220fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger        } else {
2210965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy            if (!bitmap.isMutable()) {
2220965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy                throw new IllegalStateException();
2230965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy            }
2241abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik            throwIfCannotDraw(bitmap);
225fc615a0f643408956fc0dc1b997871e2b27cee7eDerek Sollenberger
226f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck            native_setBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), true);
2270965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy            mDensity = bitmap.mDensity;
2280965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy        }
2290965a3244b4c3009d08db2e084cdcb681ef66d26Romain Guy
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBitmap = bitmap;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
232c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2345c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita     * setBitmap() variant for native callers with a raw bitmap handle.
2355c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita     */
2365c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita    private void setNativeBitmap(long bitmapHandle) {
2375c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_setBitmap(mNativeCanvasWrapper, bitmapHandle, false);
2385c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita    }
2395c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita
2405c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita    /**
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the viewport dimensions if this canvas is GL based. If it is not,
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this method is ignored and no exception is thrown.
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
244163935113919a184122b8b3bd672ef08c8df65dcRomain Guy     * @param width The width of the viewport
245163935113919a184122b8b3bd672ef08c8df65dcRomain Guy     * @param height The height of the viewport
246c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     *
247163935113919a184122b8b3bd672ef08c8df65dcRomain Guy     * @hide
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
249797b95b26bbb7557678af78b9a2a61830158920fChris Craik    public void setViewport(int width, int height) {}
250797b95b26bbb7557678af78b9a2a61830158920fChris Craik
251cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    /** @hide */
252cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    public void setHighContrastText(boolean highContrastText) {}
253cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
2548afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    /** @hide */
2558afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertReorderBarrier() {}
2568afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
2578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    /** @hide */
2588afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertInorderBarrier() {}
2598afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
260797b95b26bbb7557678af78b9a2a61830158920fChris Craik    /**
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return true if the device that the current layer draws into is opaque
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (i.e. does not support per-pixel alpha).
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the device that the current layer draws into is opaque
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
26695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public boolean isOpaque() {
26795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_isOpaque(mNativeCanvasWrapper);
26895d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the width of the current drawing layer
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the width of the current drawing layer
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
27595d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public int getWidth() {
27695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_getWidth(mNativeCanvasWrapper);
27795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the height of the current drawing layer
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the height of the current drawing layer
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
28495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public int getHeight() {
28595d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_getHeight(mNativeCanvasWrapper);
28695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
28996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>Returns the target density of the canvas.  The default density is
29096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * derived from the density of its backing bitmap, or
29196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * {@link Bitmap#DENSITY_NONE} if there is not one.</p>
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
29396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @return Returns the current target density of the canvas, which is used
29496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * to determine the scaling factor when drawing a bitmap into it.
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
29611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #setDensity(int)
297051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @see Bitmap#getDensity()
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
29911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getDensity() {
30011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return mDensity;
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
30496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>Specifies the density for this Canvas' backing bitmap.  This modifies
30596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * the target density of the canvas itself, as well as the density of its
30696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * backing bitmap via {@link Bitmap#setDensity(int) Bitmap.setDensity(int)}.
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
30896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @param density The new target density of the canvas, which is used
30996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * to determine the scaling factor when drawing a bitmap into it.  Use
31096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * {@link Bitmap#DENSITY_NONE} to disable bitmap scaling.
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
31211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #getDensity()
313051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @see Bitmap#setDensity(int)
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
31511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public void setDensity(int density) {
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBitmap != null) {
31711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            mBitmap.setDensity(density);
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        mDensity = density;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3220d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn    /** @hide */
3230d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn    public void setScreenDensity(int density) {
3240d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn        mScreenDensity = density;
3250d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn    }
326f61970fc79e9c5cf340fa942597628242361864aRomain Guy
327f61970fc79e9c5cf340fa942597628242361864aRomain Guy    /**
328f61970fc79e9c5cf340fa942597628242361864aRomain Guy     * Returns the maximum allowed width for bitmaps drawn with this canvas.
329f61970fc79e9c5cf340fa942597628242361864aRomain Guy     * Attempting to draw with a bitmap wider than this value will result
330f61970fc79e9c5cf340fa942597628242361864aRomain Guy     * in an error.
331051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
332051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @see #getMaximumBitmapHeight()
333f61970fc79e9c5cf340fa942597628242361864aRomain Guy     */
334f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapWidth() {
335f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return MAXMIMUM_BITMAP_SIZE;
336f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
337051910b9f998030dacb8a0722588cc715813fde1Raph Levien
338f61970fc79e9c5cf340fa942597628242361864aRomain Guy    /**
339f61970fc79e9c5cf340fa942597628242361864aRomain Guy     * Returns the maximum allowed height for bitmaps drawn with this canvas.
340f61970fc79e9c5cf340fa942597628242361864aRomain Guy     * Attempting to draw with a bitmap taller than this value will result
341f61970fc79e9c5cf340fa942597628242361864aRomain Guy     * in an error.
342051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
343051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @see #getMaximumBitmapWidth()
344f61970fc79e9c5cf340fa942597628242361864aRomain Guy     */
345f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapHeight() {
346f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return MAXMIMUM_BITMAP_SIZE;
347f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
348f61970fc79e9c5cf340fa942597628242361864aRomain Guy
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // the SAVE_FLAG constants must match their native equivalents
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
351ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    /** @hide */
352ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    @IntDef(flag = true,
353ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            value = {
354ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese                MATRIX_SAVE_FLAG,
355ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese                CLIP_SAVE_FLAG,
356ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese                HAS_ALPHA_LAYER_SAVE_FLAG,
357ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese                FULL_COLOR_LAYER_SAVE_FLAG,
358ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese                CLIP_TO_LAYER_SAVE_FLAG,
359ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese                ALL_SAVE_FLAG
360ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            })
361ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    @Retention(RetentionPolicy.SOURCE)
362ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public @interface Saveflags {}
363ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese
364f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik    /**
365f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Restore the current matrix when restore() is called.
366f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     */
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MATRIX_SAVE_FLAG = 0x01;
368f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik
369f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik    /**
370f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Restore the current clip when restore() is called.
371f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     */
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int CLIP_SAVE_FLAG = 0x02;
373f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik
374f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik    /**
375f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * The layer requires a per-pixel alpha channel.
376f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     */
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
378f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik
379f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik    /**
380f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * The layer requires full 8-bit precision for each color channel.
381f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     */
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
383f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik
384f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik    /**
385f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Clip drawing to the bounds of the offscreen layer, omit at your own peril.
386f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p class="note"><strong>Note:</strong> it is strongly recommended to not
387f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * omit this flag for any call to <code>saveLayer()</code> and
388f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <code>saveLayerAlpha()</code> variants. Not passing this flag generally
389f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * triggers extremely poor performance with hardware accelerated rendering.
390f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     */
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
392f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik
393f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik    /**
394f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Restore everything when restore() is called (standard save flags).
395f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p class="note"><strong>Note:</strong> for performance reasons, it is
396f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * strongly recommended to pass this - the complete set of flags - to any
397f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * call to <code>saveLayer()</code> and <code>saveLayerAlpha()</code>
398f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * variants.
399f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     */
400051910b9f998030dacb8a0722588cc715813fde1Raph Levien    public static final int ALL_SAVE_FLAG = 0x1F;
401051910b9f998030dacb8a0722588cc715813fde1Raph Levien
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
403f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Saves the current matrix and clip onto a private stack.
404f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p>
405f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Subsequent calls to translate,scale,rotate,skew,concat or clipRect,
406f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * clipPath will all operate as usual, but when the balancing call to
407f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * restore() is made, those calls will be forgotten, and the settings that
408f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * existed before the save() will be reinstated.
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The value to pass to restoreToCount() to balance this save()
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
41295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public int save() {
41395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_save(mNativeCanvasWrapper, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
41495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
415051910b9f998030dacb8a0722588cc715813fde1Raph Levien
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Based on saveFlags, can save the current matrix and clip onto a private
418f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * stack.
419f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p class="note"><strong>Note:</strong> if possible, use the
420f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * parameter-less save(). It is simpler and faster than individually
421f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * disabling the saving of matrix or clip with this method.
422f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p>
423f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Subsequent calls to translate,scale,rotate,skew,concat or clipRect,
424f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * clipPath will all operate as usual, but when the balancing call to
425f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * restore() is made, those calls will be forgotten, and the settings that
426f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * existed before the save() will be reinstated.
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param saveFlags flag bits that specify which parts of the Canvas state
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                  to save/restore
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The value to pass to restoreToCount() to balance this save()
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
432ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public int save(@Saveflags int saveFlags) {
43395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_save(mNativeCanvasWrapper, saveFlags);
43495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
437f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * This behaves the same as save(), but in addition it allocates and
438f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * redirects drawing to an offscreen bitmap.
439f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p class="note"><strong>Note:</strong> this method is very expensive,
440f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * incurring more than double rendering cost for contained content. Avoid
441f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * using this method, especially if the bounds provided are large, or if
442f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * the {@link #CLIP_TO_LAYER_SAVE_FLAG} is omitted from the
443f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * {@code saveFlags} parameter. It is recommended to use a
444f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * {@link android.view.View#LAYER_TYPE_HARDWARE hardware layer} on a View
445f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * to apply an xfermode, color filter, or alpha, as it will perform much
446f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * better than this method.
447f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p>
448f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * All drawing calls are directed to a newly allocated offscreen bitmap.
449f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Only when the balancing call to restore() is made, is that offscreen
450f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * buffer drawn back to the current target of the Canvas (either the
451f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * screen, it's target Bitmap, or the previous layer).
452f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p>
453f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Attributes of the Paint - {@link Paint#getAlpha() alpha},
454f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * {@link Paint#getXfermode() Xfermode}, and
455f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * {@link Paint#getColorFilter() ColorFilter} are applied when the
456f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * offscreen bitmap is drawn back when restore() is called.
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bounds May be null. The maximum size the offscreen bitmap
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               needs to be (in local coordinates)
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  This is copied, and is applied to the offscreen when
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               restore() is called.
462f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * @param saveFlags see _SAVE_FLAG constants, generally {@link #ALL_SAVE_FLAG} is recommended
463f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     *               for performance reasons.
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return       value to pass to restoreToCount() to balance this save()
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
466ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags) {
4679bc13a353fa8fac323839268789ef661b219530cChris Craik        if (bounds == null) {
4689bc13a353fa8fac323839268789ef661b219530cChris Craik            bounds = new RectF(getClipBounds());
4699bc13a353fa8fac323839268789ef661b219530cChris Craik        }
4709bc13a353fa8fac323839268789ef661b219530cChris Craik        return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
472c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
473c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    /**
474c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     * Convenience for saveLayer(bounds, paint, {@link #ALL_SAVE_FLAG})
475c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     */
476ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint) {
477c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik        return saveLayer(bounds, paint, ALL_SAVE_FLAG);
478c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    }
479c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Helper version of saveLayer() that takes 4 values rather than a RectF.
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
483ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public int saveLayer(float left, float top, float right, float bottom, @Nullable Paint paint,
484ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @Saveflags int saveFlags) {
4855c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_saveLayer(mNativeCanvasWrapper, left, top, right, bottom,
486dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint != null ? paint.getNativeInstance() : 0,
487f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy                saveFlags);
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
491c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     * Convenience for saveLayer(left, top, right, bottom, paint, {@link #ALL_SAVE_FLAG})
492c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     */
493ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public int saveLayer(float left, float top, float right, float bottom, @Nullable Paint paint) {
494c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik        return saveLayer(left, top, right, bottom, paint, ALL_SAVE_FLAG);
495c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    }
496c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
497c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    /**
498f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * This behaves the same as save(), but in addition it allocates and
499f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * redirects drawing to an offscreen bitmap.
500f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p class="note"><strong>Note:</strong> this method is very expensive,
501f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * incurring more than double rendering cost for contained content. Avoid
502f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * using this method, especially if the bounds provided are large, or if
503f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * the {@link #CLIP_TO_LAYER_SAVE_FLAG} is omitted from the
504f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * {@code saveFlags} parameter. It is recommended to use a
505f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * {@link android.view.View#LAYER_TYPE_HARDWARE hardware layer} on a View
506f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * to apply an xfermode, color filter, or alpha, as it will perform much
507f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * better than this method.
508f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p>
509f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * All drawing calls are directed to a newly allocated offscreen bitmap.
510f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * Only when the balancing call to restore() is made, is that offscreen
511f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * buffer drawn back to the current target of the Canvas (either the
512f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * screen, it's target Bitmap, or the previous layer).
513f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * <p>
514f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * The {@code alpha} parameter is applied when the offscreen bitmap is
515f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * drawn back when restore() is called.
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bounds    The maximum size the offscreen bitmap needs to be
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                  (in local coordinates)
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param alpha     The alpha to apply to the offscreen when when it is
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        drawn during restore()
521f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     * @param saveFlags see _SAVE_FLAG constants, generally {@link #ALL_SAVE_FLAG} is recommended
522f37a364a530c5c055cf4634f0b0463454a252b0fChris Craik     *                  for performance reasons.
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return          value to pass to restoreToCount() to balance this call
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5259bc13a353fa8fac323839268789ef661b219530cChris Craik    public int saveLayerAlpha(@Nullable RectF bounds, int alpha, @Saveflags int saveFlags) {
5269bc13a353fa8fac323839268789ef661b219530cChris Craik        if (bounds == null) {
5279bc13a353fa8fac323839268789ef661b219530cChris Craik            bounds = new RectF(getClipBounds());
5289bc13a353fa8fac323839268789ef661b219530cChris Craik        }
5299bc13a353fa8fac323839268789ef661b219530cChris Craik        return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
531c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
532c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    /**
533c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     * Convenience for saveLayerAlpha(bounds, alpha, {@link #ALL_SAVE_FLAG})
534c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     */
5359bc13a353fa8fac323839268789ef661b219530cChris Craik    public int saveLayerAlpha(@Nullable RectF bounds, int alpha) {
536c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik        return saveLayerAlpha(bounds, alpha, ALL_SAVE_FLAG);
537c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    }
538c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Helper for saveLayerAlpha() that takes 4 values instead of a RectF.
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
542f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
543ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @Saveflags int saveFlags) {
5449bc13a353fa8fac323839268789ef661b219530cChris Craik        alpha = Math.min(255, Math.max(0, alpha));
5455c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_saveLayerAlpha(mNativeCanvasWrapper, left, top, right, bottom,
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                     alpha, saveFlags);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
550c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     * Helper for saveLayerAlpha(left, top, right, bottom, alpha, {@link #ALL_SAVE_FLAG})
551c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik     */
552c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha) {
553c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik        return saveLayerAlpha(left, top, right, bottom, alpha, ALL_SAVE_FLAG);
554c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    }
555c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik
556c306ad61a791bae34ed83b339f27cb67a1d91b53Chris Craik    /**
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This call balances a previous call to save(), and is used to remove all
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * modifications to the matrix/clip state since the last save call. It is
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * an error to call restore() more times than save() was called.
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
56195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public void restore() {
5623891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated();
5633891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        native_restore(mNativeCanvasWrapper, throwOnUnderflow);
56495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the number of matrix/clip states on the Canvas' private stack.
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This will equal # save() calls - # restore() calls.
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
57095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public int getSaveCount() {
57195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_getSaveCount(mNativeCanvasWrapper);
57295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Efficient way to pop any calls to save() that happened after the save
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * count reached saveCount. It is an error for saveCount to be less than 1.
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example:
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *    int count = canvas.save();
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *    ... // more calls potentially to save()
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *    canvas.restoreToCount(count);
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *    // now the canvas is back in the same state it was before the initial
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *    // call to save().
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param saveCount The save level to restore to.
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
58795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public void restoreToCount(int saveCount) {
5883891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated();
5893891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik        native_restoreToCount(mNativeCanvasWrapper, saveCount, throwOnUnderflow);
59095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preconcat the current matrix with the specified translation
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dx The distance to translate in X
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dy The distance to translate in Y
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
59895d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public void translate(float dx, float dy) {
59995d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        native_translate(mNativeCanvasWrapper, dx, dy);
60095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preconcat the current matrix with the specified scale.
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sx The amount to scale in X
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sy The amount to scale in Y
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
60895d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public void scale(float sx, float sy) {
60995d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        native_scale(mNativeCanvasWrapper, sx, sy);
61095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preconcat the current matrix with the specified scale.
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sx The amount to scale in X
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sy The amount to scale in Y
617cc3ec6cdb2b892eb29513e72d8b205acbe997b25Gilles Debunne     * @param px The x-coord for the pivot point (unchanged by the scale)
618cc3ec6cdb2b892eb29513e72d8b205acbe997b25Gilles Debunne     * @param py The y-coord for the pivot point (unchanged by the scale)
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void scale(float sx, float sy, float px, float py) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        translate(px, py);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        scale(sx, sy);
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        translate(-px, -py);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preconcat the current matrix with the specified rotation.
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param degrees The amount to rotate, in degrees
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
63195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public void rotate(float degrees) {
63295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        native_rotate(mNativeCanvasWrapper, degrees);
63395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preconcat the current matrix with the specified rotation.
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param degrees The amount to rotate, in degrees
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param px The x-coord for the pivot point (unchanged by the rotation)
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param py The y-coord for the pivot point (unchanged by the rotation)
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void rotate(float degrees, float px, float py) {
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        translate(px, py);
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rotate(degrees);
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        translate(-px, -py);
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preconcat the current matrix with the specified skew.
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sx The amount to skew in X
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sy The amount to skew in Y
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
65495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public void skew(float sx, float sy) {
65595d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        native_skew(mNativeCanvasWrapper, sx, sy);
65695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6594e7b772b733593fbe25c733e95b8dcea293234b6Romain Guy     * Preconcat the current matrix with the specified matrix. If the specified
6604e7b772b733593fbe25c733e95b8dcea293234b6Romain Guy     * matrix is null, this method does nothing.
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param matrix The matrix to preconcatenate with the current matrix
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
664ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void concat(@Nullable Matrix matrix) {
6655c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        if (matrix != null) native_concat(mNativeCanvasWrapper, matrix.native_instance);
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
667051910b9f998030dacb8a0722588cc715813fde1Raph Levien
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Completely replace the current matrix with the specified matrix. If the
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * matrix parameter is null, then the current matrix is reset to identity.
671051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
672f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * <strong>Note:</strong> it is recommended to use {@link #concat(Matrix)},
673f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * {@link #scale(float, float)}, {@link #translate(float, float)} and
674f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * {@link #rotate(float)} instead of this method.
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param matrix The matrix to replace the current matrix with. If it is
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               null, set the current matrix to identity.
678051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
679051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @see #concat(Matrix)
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
681ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void setMatrix(@Nullable Matrix matrix) {
6825c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_setMatrix(mNativeCanvasWrapper,
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         matrix == null ? 0 : matrix.native_instance);
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
685051910b9f998030dacb8a0722588cc715813fde1Raph Levien
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return, in ctm, the current transformation matrix. This does not alter
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the matrix in the canvas, but just returns a copy of it.
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
690f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy    @Deprecated
691ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void getMatrix(@NonNull Matrix ctm) {
6925c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_getCTM(mNativeCanvasWrapper, ctm.native_instance);
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
69441030da16856c8869e1e51d4a0405432fa96614eRomain Guy
69541030da16856c8869e1e51d4a0405432fa96614eRomain Guy    /**
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return a new matrix with a copy of the canvas' current transformation
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * matrix.
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
69965447287cb4112cf74483c87be70bcd00b622e2dRomain Guy    @Deprecated
700ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public final @NonNull Matrix getMatrix() {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Matrix m = new Matrix();
702f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy        //noinspection deprecation
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getMatrix(m);
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return m;
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
706051910b9f998030dacb8a0722588cc715813fde1Raph Levien
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Modify the current clip with the specified rectangle.
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect The rect to intersect with the current clip
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op How the clip is modified
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting clip is non-empty
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
714ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRect(@NonNull RectF rect, @NonNull Region.Op op) {
7155c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_clipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
716f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy                op.nativeInt);
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Modify the current clip with the specified rectangle, which is
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * expressed in local coordinates.
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect The rectangle to intersect with the current clip.
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op How the clip is modified
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting clip is non-empty
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
727ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRect(@NonNull Rect rect, @NonNull Region.Op op) {
7285c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_clipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
729f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy                op.nativeInt);
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intersect the current clip with the specified rectangle, which is
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * expressed in local coordinates.
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect The rectangle to intersect with the current clip.
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting clip is non-empty
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
739ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRect(@NonNull RectF rect) {
74095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_clipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
74195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                Region.Op.INTERSECT.nativeInt);
74295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
74395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intersect the current clip with the specified rectangle, which is
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * expressed in local coordinates.
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect The rectangle to intersect with the current clip.
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting clip is non-empty
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
751ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRect(@NonNull Rect rect) {
75295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_clipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
75395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                Region.Op.INTERSECT.nativeInt);
75495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
755051910b9f998030dacb8a0722588cc715813fde1Raph Levien
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Modify the current clip with the specified rectangle, which is
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * expressed in local coordinates.
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left   The left side of the rectangle to intersect with the
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               current clip
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top    The top of the rectangle to intersect with the current
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               clip
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param right  The right side of the rectangle to intersect with the
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               current clip
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bottom The bottom of the rectangle to intersect with the current
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               clip
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op     How the clip is modified
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return       true if the resulting clip is non-empty
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
771ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRect(float left, float top, float right, float bottom,
772ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Region.Op op) {
7735c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom, op.nativeInt);
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intersect the current clip with the specified rectangle, which is
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * expressed in local coordinates.
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left   The left side of the rectangle to intersect with the
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               current clip
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top    The top of the rectangle to intersect with the current clip
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param right  The right side of the rectangle to intersect with the
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               current clip
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bottom The bottom of the rectangle to intersect with the current
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               clip
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return       true if the resulting clip is non-empty
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
78995d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public boolean clipRect(float left, float top, float right, float bottom) {
79095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom,
79195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                Region.Op.INTERSECT.nativeInt);
79295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
793f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intersect the current clip with the specified rectangle, which is
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * expressed in local coordinates.
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left   The left side of the rectangle to intersect with the
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               current clip
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top    The top of the rectangle to intersect with the current clip
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param right  The right side of the rectangle to intersect with the
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               current clip
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bottom The bottom of the rectangle to intersect with the current
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               clip
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return       true if the resulting clip is non-empty
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
80795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    public boolean clipRect(int left, int top, int right, int bottom) {
80895d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom,
80995d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                Region.Op.INTERSECT.nativeInt);
81095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
811f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        * Modify the current clip with the specified path.
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path The path to operate on the current clip
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op   How the clip is modified
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return     true if the resulting is non-empty
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
819ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipPath(@NonNull Path path, @NonNull Region.Op op) {
8205c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_clipPath(mNativeCanvasWrapper, path.ni(), op.nativeInt);
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
822051910b9f998030dacb8a0722588cc715813fde1Raph Levien
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intersect the current clip with the specified path.
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path The path to intersect with the current clip
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return     true if the resulting is non-empty
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
829ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipPath(@NonNull Path path) {
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return clipPath(path, Region.Op.INTERSECT);
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
832051910b9f998030dacb8a0722588cc715813fde1Raph Levien
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Modify the current clip with the specified region. Note that unlike
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipRect() and clipPath() which transform their arguments by the
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current matrix, clipRegion() assumes its argument is already in the
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * coordinate system of the current layer's bitmap, and so not
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * transformation is performed.
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param region The region to operate on the current clip, based on op
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param op How the clip is modified
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting is non-empty
8430d181540e0c96da454f45e65987f690b27b929d9Derek Sollenberger     *
8440d181540e0c96da454f45e65987f690b27b929d9Derek Sollenberger     * @deprecated Unlike all other clip calls this API does not respect the
8450d181540e0c96da454f45e65987f690b27b929d9Derek Sollenberger     *             current matrix. Use {@link #clipRect(Rect)} as an alternative.
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
847ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRegion(@NonNull Region region, @NonNull Region.Op op) {
8485c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_clipRegion(mNativeCanvasWrapper, region.ni(), op.nativeInt);
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intersect the current clip with the specified region. Note that unlike
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipRect() and clipPath() which transform their arguments by the
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current matrix, clipRegion() assumes its argument is already in the
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * coordinate system of the current layer's bitmap, and so not
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * transformation is performed.
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param region The region to operate on the current clip, based on op
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the resulting is non-empty
8600d181540e0c96da454f45e65987f690b27b929d9Derek Sollenberger     *
8610d181540e0c96da454f45e65987f690b27b929d9Derek Sollenberger     * @deprecated Unlike all other clip calls this API does not respect the
8620d181540e0c96da454f45e65987f690b27b929d9Derek Sollenberger     *             current matrix. Use {@link #clipRect(Rect)} as an alternative.
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
864ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean clipRegion(@NonNull Region region) {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return clipRegion(region, Region.Op.INTERSECT);
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
867051910b9f998030dacb8a0722588cc715813fde1Raph Levien
868ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public @Nullable DrawFilter getDrawFilter() {
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDrawFilter;
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
871051910b9f998030dacb8a0722588cc715813fde1Raph Levien
872ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void setDrawFilter(@Nullable DrawFilter filter) {
87336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long nativeFilter = 0;
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (filter != null) {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nativeFilter = filter.mNativeInt;
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDrawFilter = filter;
8785c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        nativeSetDrawFilter(mNativeCanvasWrapper, nativeFilter);
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum EdgeType {
882d320001807168f5565bab9807ef13c111096bbb3Chet Haase
883d320001807168f5565bab9807ef13c111096bbb3Chet Haase        /**
884d320001807168f5565bab9807ef13c111096bbb3Chet Haase         * Black-and-White: Treat edges by just rounding to nearest pixel boundary
885d320001807168f5565bab9807ef13c111096bbb3Chet Haase         */
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        BW(0),  //!< treat edges by just rounding to nearest pixel boundary
887d320001807168f5565bab9807ef13c111096bbb3Chet Haase
888d320001807168f5565bab9807ef13c111096bbb3Chet Haase        /**
889d320001807168f5565bab9807ef13c111096bbb3Chet Haase         * Antialiased: Treat edges by rounding-out, since they may be antialiased
890d320001807168f5565bab9807ef13c111096bbb3Chet Haase         */
891d320001807168f5565bab9807ef13c111096bbb3Chet Haase        AA(1);
892051910b9f998030dacb8a0722588cc715813fde1Raph Levien
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EdgeType(int nativeInt) {
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = nativeInt;
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
896c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
897c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        /**
898c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy         * @hide
899c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy         */
900c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        public final int nativeInt;
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return true if the specified rectangle, after being transformed by the
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current matrix, would lie completely outside of the current clip. Call
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this to check if an area you intend to draw into is clipped out (and
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * therefore you can skip making the draw calls).
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect  the rect to compare with the current clip
910d320001807168f5565bab9807ef13c111096bbb3Chet Haase     * @param type  {@link Canvas.EdgeType#AA} if the path should be considered antialiased,
911d320001807168f5565bab9807ef13c111096bbb3Chet Haase     *              since that means it may affect a larger area (more pixels) than
912d320001807168f5565bab9807ef13c111096bbb3Chet Haase     *              non-antialiased ({@link Canvas.EdgeType#BW}).
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return      true if the rect (transformed by the canvas' matrix)
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              does not intersect with the canvas' clip
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
916ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean quickReject(@NonNull RectF rect, @NonNull EdgeType type) {
91795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        return native_quickReject(mNativeCanvasWrapper,
91895d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                rect.left, rect.top, rect.right, rect.bottom);
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return true if the specified path, after being transformed by the
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current matrix, would lie completely outside of the current clip. Call
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this to check if an area you intend to draw into is clipped out (and
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * therefore you can skip making the draw calls). Note: for speed it may
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * return false even if the path itself might not intersect the clip
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (i.e. the bounds of the path intersects, but the path does not).
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path        The path to compare with the current clip
930d320001807168f5565bab9807ef13c111096bbb3Chet Haase     * @param type        {@link Canvas.EdgeType#AA} if the path should be considered antialiased,
931d320001807168f5565bab9807ef13c111096bbb3Chet Haase     *                    since that means it may affect a larger area (more pixels) than
932d320001807168f5565bab9807ef13c111096bbb3Chet Haase     *                    non-antialiased ({@link Canvas.EdgeType#BW}).
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return            true if the path (transformed by the canvas' matrix)
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    does not intersect with the canvas' clip
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
936ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean quickReject(@NonNull Path path, @NonNull EdgeType type) {
9375c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_quickReject(mNativeCanvasWrapper, path.ni());
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return true if the specified rectangle, after being transformed by the
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current matrix, would lie completely outside of the current clip. Call
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this to check if an area you intend to draw into is clipped out (and
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * therefore you can skip making the draw calls).
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left        The left side of the rectangle to compare with the
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    current clip
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top         The top of the rectangle to compare with the current
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    clip
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param right       The right side of the rectangle to compare with the
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    current clip
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bottom      The bottom of the rectangle to compare with the
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    current clip
954d320001807168f5565bab9807ef13c111096bbb3Chet Haase     * @param type        {@link Canvas.EdgeType#AA} if the path should be considered antialiased,
955d320001807168f5565bab9807ef13c111096bbb3Chet Haase     *                    since that means it may affect a larger area (more pixels) than
956d320001807168f5565bab9807ef13c111096bbb3Chet Haase     *                    non-antialiased ({@link Canvas.EdgeType#BW}).
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return            true if the rect (transformed by the canvas' matrix)
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    does not intersect with the canvas' clip
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
960ca79cf69d09efa0c327e9b1237d86a119aea5da7Derek Sollenberger    public boolean quickReject(float left, float top, float right, float bottom,
961ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull EdgeType type) {
9625c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_quickReject(mNativeCanvasWrapper, left, top, right, bottom);
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
966708144e828b1a549567ce50cd8ed3cda62930501Derek Sollenberger     * Return the bounds of the current clip (in local coordinates) in the
967708144e828b1a549567ce50cd8ed3cda62930501Derek Sollenberger     * bounds parameter, and return true if it is non-empty. This can be useful
968708144e828b1a549567ce50cd8ed3cda62930501Derek Sollenberger     * in a way similar to quickReject, in that it tells you that drawing
969708144e828b1a549567ce50cd8ed3cda62930501Derek Sollenberger     * outside of these bounds will be clipped out.
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bounds Return the clip bounds here. If it is null, ignore it but
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               still return true if the current clip is non-empty.
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the current clip is non-empty.
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
975ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public boolean getClipBounds(@Nullable Rect bounds) {
9765c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        return native_getClipBounds(mNativeCanvasWrapper, bounds);
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
978051910b9f998030dacb8a0722588cc715813fde1Raph Levien
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
980708144e828b1a549567ce50cd8ed3cda62930501Derek Sollenberger     * Retrieve the bounds of the current clip (in local coordinates).
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the clip bounds, or [0, 0, 0, 0] if the clip is empty.
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
984ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public final @NonNull Rect getClipBounds() {
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Rect r = new Rect();
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getClipBounds(r);
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return r;
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
989051910b9f998030dacb8a0722588cc715813fde1Raph Levien
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fill the entire canvas' bitmap (restricted to the current clip) with the
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified RGB color, using srcover porterduff mode.
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param r red component (0..255) of the color to draw onto the canvas
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param g green component (0..255) of the color to draw onto the canvas
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param b blue component (0..255) of the color to draw onto the canvas
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void drawRGB(int r, int g, int b) {
9998872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        drawColor(Color.rgb(r, g, b));
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fill the entire canvas' bitmap (restricted to the current clip) with the
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified ARGB color, using srcover porterduff mode.
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param a alpha component (0..255) of the color to draw onto the canvas
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param r red component (0..255) of the color to draw onto the canvas
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param g green component (0..255) of the color to draw onto the canvas
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param b blue component (0..255) of the color to draw onto the canvas
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void drawARGB(int a, int r, int g, int b) {
10128872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        drawColor(Color.argb(a, r, g, b));
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fill the entire canvas' bitmap (restricted to the current clip) with the
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified color, using srcover porterduff mode.
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color the color to draw onto the canvas
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
102180756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void drawColor(@ColorInt int color) {
10228872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        native_drawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fill the entire canvas' bitmap (restricted to the current clip) with the
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified color and porter-duff xfermode.
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color the color to draw with
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode  the porter-duff mode to apply to the color
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
103280756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
10335c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawColor(mNativeCanvasWrapper, color, mode.nativeInt);
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fill the entire canvas' bitmap (restricted to the current clip) with
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the specified paint. This is equivalent (but faster) to drawing an
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * infinitely large rectangle with the specified paint.
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used to draw onto the canvas
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1043ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPaint(@NonNull Paint paint) {
1044dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1046051910b9f998030dacb8a0722588cc715813fde1Raph Levien
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw a series of points. Each point is centered at the coordinate
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified by pts[], and its diameter is specified by the paint's stroke
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * width (as transformed by the canvas' CTM), with special treatment for
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a stroke width of 0, which always draws exactly 1 pixel (or at most 4
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if antialiasing is enabled). The shape of the point is controlled by
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the paint's Cap type. The shape is a square, unless the cap type is
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Round, in which case the shape is a circle.
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pts      Array of points to draw [x0 y0 x1 y1 x2 y2 ...]
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   Number of values to skip before starting to draw.
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count    The number of values to process, after skipping offset
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 of them. Since one point uses two values, the number of
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 "points" that are drawn is really (count >> 1).
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint    The paint used to draw the points
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1063b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye    public void drawPoints(@Size(multiple=2) float[] pts, int offset, int count,
1064b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye            @NonNull Paint paint) {
1065dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
106695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Helper for drawPoints() that assumes you want to draw the entire array
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1071b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye    public void drawPoints(@Size(multiple=2) @NonNull float[] pts, @NonNull Paint paint) {
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawPoints(pts, 0, pts.length, paint);
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Helper for drawPoints() for drawing a single point.
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1078ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPoint(float x, float y, @NonNull Paint paint) {
1079dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
108095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw a line segment with the specified start and stop x,y coordinates,
1084a5ef27da958acb84014b9f6ca4622c02be02fe22Chris Craik     * using the specified paint.
1085a5ef27da958acb84014b9f6ca4622c02be02fe22Chris Craik     *
1086a5ef27da958acb84014b9f6ca4622c02be02fe22Chris Craik     * <p>Note that since a line is always "framed", the Style is ignored in the paint.</p>
1087a5ef27da958acb84014b9f6ca4622c02be02fe22Chris Craik     *
1088a5ef27da958acb84014b9f6ca4622c02be02fe22Chris Craik     * <p>Degenerate lines (length is 0) will not be drawn.</p>
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param startX The x-coordinate of the start point of the line
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param startY The y-coordinate of the start point of the line
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  The paint used to draw the line
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1094ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawLine(float startX, float startY, float stopX, float stopY,
1095ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
1096dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw a series of lines. Each line is taken from 4 consecutive values
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the pts array. Thus to draw 1 line, the array must contain at least 4
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * values. This is logically the same as drawing the array as follows:
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawLine(pts[0], pts[1], pts[2], pts[3]) followed by
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawLine(pts[4], pts[5], pts[6], pts[7]) and so on.
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pts      Array of points to draw [x0 y0 x1 y1 x2 y2 ...]
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   Number of values in the array to skip before drawing.
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count    The number of values in the array to process, after
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 skipping "offset" of them. Since each line uses 4 values,
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the number of "lines" that are drawn is really
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 (count >> 2).
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint    The paint used to draw the points
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1114b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye    public void drawLines(@Size(min=4,multiple=2) float[] pts, int offset, int count, Paint paint) {
1115dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
111695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    }
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1118b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye    public void drawLines(@Size(min=4,multiple=2) @NonNull float[] pts, @NonNull Paint paint) {
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawLines(pts, 0, pts.length, paint);
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified Rect using the specified paint. The rectangle will
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be filled or framed based on the Style in the paint.
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect  The rect to be drawn
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used to draw the rect
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1129ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
113095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita        native_drawRect(mNativeCanvasWrapper,
1131dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified Rect using the specified Paint. The rectangle
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be filled or framed based on the Style in the paint.
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param r        The rectangle to be drawn.
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint    The paint used to draw the rectangle
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1141ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawRect(@NonNull Rect r, @NonNull Paint paint) {
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawRect(r.left, r.top, r.right, r.bottom, paint);
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1144051910b9f998030dacb8a0722588cc715813fde1Raph Levien
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified Rect using the specified paint. The rectangle will
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be filled or framed based on the Style in the paint.
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left   The left side of the rectangle to be drawn
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top    The top side of the rectangle to be drawn
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param right  The right side of the rectangle to be drawn
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bottom The bottom side of the rectangle to be drawn
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  The paint used to draw the rect
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1156ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {
1157dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified oval using the specified paint. The oval will be
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * filled or framed based on the Style in the paint.
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param oval The rectangle bounds of the oval to be drawn
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1166ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (oval == null) {
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException();
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
117024609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese        drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
117124609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    }
117224609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese
117324609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    /**
117424609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * Draw the specified oval using the specified paint. The oval will be
117524609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * filled or framed based on the Style in the paint.
117624609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     */
117724609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {
1178dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified circle using the specified paint. If radius is <= 0,
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * then nothing will be drawn. The circle will be filled or framed based
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * on the Style in the paint.
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cx     The x-coordinate of the center of the cirle to be drawn
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cy     The y-coordinate of the center of the cirle to be drawn
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param radius The radius of the cirle to be drawn
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  The paint used to draw the circle
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1191ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
1192dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11964a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * <p>Draw the specified arc, which will be scaled to fit inside the
11974a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * specified oval.</p>
1198051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
11994a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * <p>If the start angle is negative or >= 360, the start angle is treated
12004a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * as start angle modulo 360.</p>
1201051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
12024a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * <p>If the sweep angle is >= 360, then the oval is drawn
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely. Note that this differs slightly from SkPath::arcTo, which
12044a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * treats the sweep angle modulo 360. If the sweep angle is negative,
12054a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * the sweep angle is treated as sweep angle modulo 360</p>
1206051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
12074a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * <p>The arc is drawn clockwise. An angle of 0 degrees correspond to the
12084a317db43d2bbc992284dd1f651751f13734d017Romain Guy     * geometric angle of 0 degrees (3 o'clock on a watch.)</p>
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param oval       The bounds of oval used to define the shape and size
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   of the arc
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param startAngle Starting angle (in degrees) where the arc begins
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sweepAngle Sweep angle (in degrees) measured clockwise
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param useCenter If true, include the center of the oval in the arc, and
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        close it if it is being stroked. This will draw a wedge
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint      The paint used to draw the arc
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1218ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,
1219ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
122024609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese        drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
122124609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese                paint);
122224609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    }
122324609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese
122424609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    /**
122524609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * <p>Draw the specified arc, which will be scaled to fit inside the
122624609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * specified oval.</p>
122724609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     *
122824609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * <p>If the start angle is negative or >= 360, the start angle is treated
122924609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * as start angle modulo 360.</p>
123024609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     *
123124609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * <p>If the sweep angle is >= 360, then the oval is drawn
123224609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * completely. Note that this differs slightly from SkPath::arcTo, which
123324609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * treats the sweep angle modulo 360. If the sweep angle is negative,
123424609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * the sweep angle is treated as sweep angle modulo 360</p>
123524609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     *
123624609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * <p>The arc is drawn clockwise. An angle of 0 degrees correspond to the
123724609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * geometric angle of 0 degrees (3 o'clock on a watch.)</p>
123824609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     *
123924609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * @param startAngle Starting angle (in degrees) where the arc begins
124024609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * @param sweepAngle Sweep angle (in degrees) measured clockwise
124124609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * @param useCenter If true, include the center of the oval in the arc, and
124224609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese                        close it if it is being stroked. This will draw a wedge
124324609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     * @param paint      The paint used to draw the arc
124424609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese     */
124524609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    public void drawArc(float left, float top, float right, float bottom, float startAngle,
124624609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese            float sweepAngle, boolean useCenter, @NonNull Paint paint) {
124724609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese        native_drawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
1248dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                useCenter, paint.getNativeInstance());
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified round-rect using the specified paint. The roundrect
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be filled or framed based on the Style in the paint.
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect  The rectangular bounds of the roundRect to be drawn
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rx    The x-radius of the oval used to round the corners
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param ry    The y-radius of the oval used to round the corners
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used to draw the roundRect
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1260ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
12614d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik        drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
12624d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik    }
12634d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik
12644d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik    /**
12654d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     * Draw the specified round-rect using the specified paint. The roundrect
12664d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     * will be filled or framed based on the Style in the paint.
12674d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     *
12684d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     * @param rx    The x-radius of the oval used to round the corners
12694d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     * @param ry    The y-radius of the oval used to round the corners
12704d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     * @param paint The paint used to draw the roundRect
12714d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik     */
12724d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik    public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
1273ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
1274dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, paint.getNativeInstance());
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified path using the specified paint. The path will be
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * filled or framed based on the Style in the paint.
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path  The path to be drawn
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used to draw the path
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1284ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPath(@NonNull Path path, @NonNull Paint paint) {
1285dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        native_drawPath(mNativeCanvasWrapper, path.ni(), paint.getNativeInstance());
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12871abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik
12881abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    /**
12891abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * @hide
12901abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     */
12911abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    protected static void throwIfCannotDraw(Bitmap bitmap) {
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bitmap.isRecycled()) {
1293f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy            throw new RuntimeException("Canvas: trying to use a recycled bitmap " + bitmap);
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12951abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        if (!bitmap.isPremultiplied() && bitmap.getConfig() == Bitmap.Config.ARGB_8888 &&
12961abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik                bitmap.hasAlpha()) {
12971abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik            throw new RuntimeException("Canvas: trying to use a non-premultiplied bitmap "
12981abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik                    + bitmap);
12991abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        }
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1303deba785f122a47915756ffd991f5540d952cf937Romain Guy     * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
1304deba785f122a47915756ffd991f5540d952cf937Romain Guy     *
13053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param patch The ninepatch object to render
1306deba785f122a47915756ffd991f5540d952cf937Romain Guy     * @param dst The destination rectangle.
1307deba785f122a47915756ffd991f5540d952cf937Romain Guy     * @param paint The paint to draw the bitmap with. may be null
1308051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
1309deba785f122a47915756ffd991f5540d952cf937Romain Guy     * @hide
1310deba785f122a47915756ffd991f5540d952cf937Romain Guy     */
1311ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst, @Nullable Paint paint) {
1312f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy        patch.drawSoftware(this, dst, paint);
1313f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    }
1314f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy
1315f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    /**
1316f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
1317f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     *
1318f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     * @param patch The ninepatch object to render
1319f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     * @param dst The destination rectangle.
1320f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     * @param paint The paint to draw the bitmap with. may be null
1321f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     *
1322f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     * @hide
1323f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy     */
1324ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst, @Nullable Paint paint) {
1325f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy        patch.drawSoftware(this, dst, paint);
1326f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    }
1327f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy
1328deba785f122a47915756ffd991f5540d952cf937Romain Guy    /**
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified bitmap, with its top/left corner at (x,y), using
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the specified paint, transformed by the current matrix.
1331051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
133211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Note: if the paint contains a maskfilter that generates a mask which
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extends beyond the bitmap's original width/height (e.g. BlurMaskFilter),
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * then the bitmap will be drawn as if it were in a Shader with CLAMP mode.
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Thus the color outside of the original width/height will be the edge
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * color replicated.
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
133811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>If the bitmap and canvas have different densities, this function
133911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * will take care of automatically scaling the bitmap to draw at the
134011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * same density as the canvas.
1341051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The bitmap to be drawn
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left   The position of the left side of the bitmap being drawn
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top    The position of the top side of the bitmap being drawn
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  The paint used to draw the bitmap (may be null)
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1347ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
13481abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
1349f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        native_drawBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), left, top,
1350dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified bitmap, scaling/translating automatically to fill
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the destination rectangle. If the source rectangle is not null, it
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specifies the subset of the bitmap to draw.
1357051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
135811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Note: if the paint contains a maskfilter that generates a mask which
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extends beyond the bitmap's original width/height (e.g. BlurMaskFilter),
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * then the bitmap will be drawn as if it were in a Shader with CLAMP mode.
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Thus the color outside of the original width/height will be the edge
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * color replicated.
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
136411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>This function <em>ignores the density associated with the bitmap</em>.
136511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * This is because the source and destination rectangle coordinate
136611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * spaces are in their respective densities, so must already have the
136711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * appropriate scaling factor applied.
1368051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The bitmap to be drawn
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param src    May be null. The subset of the bitmap to be drawn
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dst    The rectangle that the bitmap will be scaled/translated
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               to fit into
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  May be null. The paint used to draw the bitmap
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1375ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
1376ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @Nullable Paint paint) {
13778872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      if (dst == null) {
13788872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          throw new NullPointerException();
13798872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      }
13808872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      throwIfCannotDraw(bitmap);
1381dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger      final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
13828872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
13838872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      float left, top, right, bottom;
13848872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      if (src == null) {
13858872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          left = top = 0;
13868872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          right = bitmap.getWidth();
13878872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          bottom = bitmap.getHeight();
13888872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      } else {
13898872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          left = src.left;
13908872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          right = src.right;
13918872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          top = src.top;
13928872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger          bottom = src.bottom;
13938872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger      }
13948872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1395f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck      native_drawBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), left, top, right, bottom,
13968872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger              dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
13978872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger              bitmap.mDensity);
13988872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger  }
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified bitmap, scaling/translating automatically to fill
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the destination rectangle. If the source rectangle is not null, it
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specifies the subset of the bitmap to draw.
1404051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
140511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Note: if the paint contains a maskfilter that generates a mask which
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extends beyond the bitmap's original width/height (e.g. BlurMaskFilter),
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * then the bitmap will be drawn as if it were in a Shader with CLAMP mode.
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Thus the color outside of the original width/height will be the edge
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * color replicated.
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
141111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>This function <em>ignores the density associated with the bitmap</em>.
141211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * This is because the source and destination rectangle coordinate
141311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * spaces are in their respective densities, so must already have the
141411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * appropriate scaling factor applied.
1415051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The bitmap to be drawn
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param src    May be null. The subset of the bitmap to be drawn
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dst    The rectangle that the bitmap will be scaled/translated
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               to fit into
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  May be null. The paint used to draw the bitmap
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1422ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
1423ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @Nullable Paint paint) {
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst == null) {
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException();
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14271abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
1428dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
14298872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
14308872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        int left, top, right, bottom;
14318872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        if (src == null) {
14328872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            left = top = 0;
14338872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            right = bitmap.getWidth();
14348872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            bottom = bitmap.getHeight();
14358872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        } else {
14368872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            left = src.left;
14378872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            right = src.right;
14388872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            top = src.top;
14398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            bottom = src.bottom;
14408872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        }
14418872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger
1442f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        native_drawBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), left, top, right, bottom,
14438872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
14448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            bitmap.mDensity);
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1446051910b9f998030dacb8a0722588cc715813fde1Raph Levien
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Treat the specified array of colors as a bitmap, and draw it. This gives
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same result as first creating a bitmap from the array, and then
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawing it, but this method avoids explicitly creating a bitmap object
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * which can be more efficient if the colors are changing often.
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colors Array of colors representing the pixels of the bitmap
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset Offset into the array of colors for the first pixel
145583d522290e56f614d0d9373d47c2b54b9e207795Brad Fitzpatrick     * @param stride The number of colors in the array between rows (must be
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               >= width or <= -width).
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x The X coordinate for where to draw the bitmap
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y The Y coordinate for where to draw the bitmap
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width The width of the bitmap
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height The height of the bitmap
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hasAlpha True if the alpha channel of the colors contains valid
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 values. If false, the alpha byte is ignored (assumed to
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 be 0xFF for every pixel).
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  May be null. The paint used to draw the bitmap
1465cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     *
1466cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * @deprecated Usage with a {@link #isHardwareAccelerated() hardware accelerated} canvas
1467cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * requires an internal copy of color buffer contents every time this method is called. Using a
1468cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * Bitmap avoids this copy, and allows the application to more explicitly control the lifetime
1469cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * and copies of pixel data.
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1471cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik    @Deprecated
1472ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y,
1473ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            int width, int height, boolean hasAlpha, @Nullable Paint paint) {
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // check for valid input
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width < 0) {
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width must be >= 0");
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height < 0) {
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("height must be >= 0");
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Math.abs(stride) < width) {
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("abs(stride) must be >= width");
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int lastScanline = offset + (height - 1) * stride;
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = colors.length;
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset < 0 || (offset + width > length) || lastScanline < 0
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || (lastScanline + width > length)) {
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // quick escape if there's nothing to draw
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width == 0 || height == 0) {
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // punch down to native for the actual draw
14955c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
1496dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint != null ? paint.getNativeInstance() : 0);
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1498cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik
1499cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik    /**
1500cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * Legacy version of drawBitmap(int[] colors, ...) that took ints for x,y
1501cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     *
1502cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * @deprecated Usage with a {@link #isHardwareAccelerated() hardware accelerated} canvas
1503cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * requires an internal copy of color buffer contents every time this method is called. Using a
1504cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * Bitmap avoids this copy, and allows the application to more explicitly control the lifetime
1505cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik     * and copies of pixel data.
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1507cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik    @Deprecated
1508ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y,
1509ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            int width, int height, boolean hasAlpha, @Nullable Paint paint) {
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // call through to the common float version
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawBitmap(colors, offset, stride, (float)x, (float)y, width, height,
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   hasAlpha, paint);
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1514cd23df6a08cf7a9bdee11e703f40bca5904d779dChris Craik
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the bitmap using the specified matrix.
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The bitmap to draw
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param matrix The matrix used to transform the bitmap when it is drawn
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  May be null. The paint used to draw the bitmap
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1522ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
1523f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getSkBitmap(), matrix.ni(),
1524dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint != null ? paint.getNativeInstance() : 0);
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15265a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
15275a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    /**
15285a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy     * @hide
15295a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy     */
15305a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    protected static void checkRange(int length, int offset, int count) {
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((offset | count) < 0 || offset + count > length) {
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1535051910b9f998030dacb8a0722588cc715813fde1Raph Levien
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the bitmap through the mesh, where mesh vertices are evenly
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * distributed across the bitmap. There are meshWidth+1 vertices across, and
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * meshHeight+1 vertices down. The verts array is accessed in row-major
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * order, so that the first meshWidth+1 vertices are distributed across the
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * top of the bitmap from left to right. A more general version of this
15425d11676414b3606792e23c269cf75b44faa1a2afChris Craik     * method is drawVertices().
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The bitmap to draw using the mesh
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param meshWidth The number of columns in the mesh. Nothing is drawn if
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                  this is 0
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param meshHeight The number of rows in the mesh. Nothing is drawn if
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   this is 0
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param verts Array of x,y pairs, specifying where the mesh should be
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              drawn. There must be at least
15515d11676414b3606792e23c269cf75b44faa1a2afChris Craik     *              (meshWidth+1) * (meshHeight+1) * 2 + vertOffset values
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              in the array
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vertOffset Number of verts elements to skip before drawing
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colors May be null. Specifies a color at each vertex, which is
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               interpolated across the cell, and whose values are
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               multiplied by the corresponding bitmap colors. If not null,
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               there must be at least (meshWidth+1) * (meshHeight+1) +
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               colorOffset values in the array.
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colorOffset Number of color elements to skip before drawing
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint  May be null. The paint used to draw the bitmap
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1562ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight,
1563ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset,
1564ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @Nullable Paint paint) {
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (meshWidth == 0 || meshHeight == 0) {
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = (meshWidth + 1) * (meshHeight + 1);
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we mul by 2 since we need two floats per vertex
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRange(verts.length, vertOffset, count * 2);
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (colors != null) {
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // no mul by 2, since we need only 1 color per vertex
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkRange(colors.length, colorOffset, count);
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1578f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        nativeDrawBitmapMesh(mNativeCanvasWrapper, bitmap.getSkBitmap(), meshWidth, meshHeight,
1579f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy                verts, vertOffset, colors, colorOffset,
1580dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint != null ? paint.getNativeInstance() : 0);
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1582f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum VertexMode {
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TRIANGLES(0),
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TRIANGLE_STRIP(1),
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TRIANGLE_FAN(2);
1587051910b9f998030dacb8a0722588cc715813fde1Raph Levien
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        VertexMode(int nativeInt) {
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = nativeInt;
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1591a566b7c3aada08d37cf08096c972e3e641bed773Romain Guy
1592a566b7c3aada08d37cf08096c972e3e641bed773Romain Guy        /**
1593a566b7c3aada08d37cf08096c972e3e641bed773Romain Guy         * @hide
1594a566b7c3aada08d37cf08096c972e3e641bed773Romain Guy         */
1595a566b7c3aada08d37cf08096c972e3e641bed773Romain Guy        public final int nativeInt;
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1597051910b9f998030dacb8a0722588cc715813fde1Raph Levien
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the array of vertices, interpreted as triangles (based on mode). The
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * verts array is required, and specifies the x,y pairs for each vertex. If
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * texs is non-null, then it is used to specify the coordinate in shader
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * coordinates to use at each vertex (the paint must have a shader in this
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * case). If there is no texs array, but there is a color array, then each
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * color is interpolated across its corresponding triangle in a gradient. If
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * both texs and colors arrays are present, then they behave as before, but
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the resulting color at each pixels is the result of multiplying the
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * colors from the shader and the color-gradient together. The indices array
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is optional, but if it is present, then it is used to specify the index
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of each triangle, rather than just walking through the arrays in order.
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode How to interpret the array of vertices
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vertexCount The number of values in the vertices array (and
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      corresponding texs and colors arrays if non-null). Each logical
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      vertex is two values (x, y), vertexCount must be a multiple of 2.
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param verts Array of vertices for the mesh
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vertOffset Number of values in the verts to skip before drawing.
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param texs May be null. If not null, specifies the coordinates to sample
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      into the current shader (e.g. bitmap tile or gradient)
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param texOffset Number of values in texs to skip before drawing.
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colors May be null. If not null, specifies a color for each
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      vertex, to be interpolated across the triangle.
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colorOffset Number of values in colors to skip before drawing.
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param indices If not null, array of indices to reference into the
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      vertex (texs, colors) array.
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param indexCount number of entries in the indices array (if not null).
1626051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @param paint Specifies the shader to use if the texs array is non-null.
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1628ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawVertices(@NonNull VertexMode mode, int vertexCount, @NonNull float[] verts,
1629ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            int vertOffset, @Nullable float[] texs, int texOffset, @Nullable int[] colors,
1630ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount,
1631ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRange(verts.length, vertOffset, vertexCount);
16338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        if (isHardwareAccelerated()) {
16348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            return;
16358dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        }
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (texs != null) {
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkRange(texs.length, texOffset, vertexCount);
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (colors != null) {
164092ce5734b52ef014c80cc6335112a027188b3eb6Erik Faye-Lund            checkRange(colors.length, colorOffset, vertexCount / 2);
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (indices != null) {
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkRange(indices.length, indexOffset, indexCount);
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16455c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        nativeDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
1646f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy                vertOffset, texs, texOffset, colors, colorOffset,
1647dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                indices, indexOffset, indexCount, paint.getNativeInstance());
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
164936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text, with origin at (x,y), using the specified paint. The
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * origin is interpreted based on the Align setting in the paint.
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text  The text to be drawn
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x     The x-coordinate of the origin of the text being drawn
16565dc973cb03889c58988703b58aefbd2397fb02c3Alan Viverette     * @param y     The y-coordinate of the baseline of the text being drawn
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used for the text (e.g. color, size, style)
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1659ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawText(@NonNull char[] text, int index, int count, float x, float y,
1660ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((index | count | (index + count) |
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (text.length - index - count)) < 0) {
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException();
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16655c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
1666dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint.getNativeInstance(), paint.mNativeTypeface);
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text, with origin at (x,y), using the specified paint. The
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * origin is interpreted based on the Align setting in the paint.
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text  The text to be drawn
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x     The x-coordinate of the origin of the text being drawn
16755dc973cb03889c58988703b58aefbd2397fb02c3Alan Viverette     * @param y     The y-coordinate of the baseline of the text being drawn
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used for the text (e.g. color, size, style)
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1678ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
16795c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
1680dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint.getNativeInstance(), paint.mNativeTypeface);
1681f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    }
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text, with origin at (x,y), using the specified paint.
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The origin is interpreted based on the Align setting in the paint.
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text  The text to be drawn
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param start The index of the first character in text to draw
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param end   (end - 1) is the index of the last character in text to draw
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x     The x-coordinate of the origin of the text being drawn
16915dc973cb03889c58988703b58aefbd2397fb02c3Alan Viverette     * @param y     The y-coordinate of the baseline of the text being drawn
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used for the text (e.g. color, size, style)
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1694ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawText(@NonNull String text, int start, int end, float x, float y,
1695ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((start | end | (end - start) | (text.length() - end)) < 0) {
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException();
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16995c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
1700dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint.getNativeInstance(), paint.mNativeTypeface);
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the specified range of text, specified by start/end, with its
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * origin at (x,y), in the specified Paint. The origin is interpreted
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * based on the Align setting in the Paint.
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text     The text to be drawn
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param start    The index of the first character in text to draw
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param end      (end - 1) is the index of the last character in text
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 to draw
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x-coordinate of origin for where to draw the text
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y-coordinate of origin for where to draw the text
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used for the text (e.g. color, size, style)
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1716ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
1717ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
1718d82f8a9a3869448e6d7d4b3fc962e34e33a1ba0eRaph Levien        if ((start | end | (end - start) | (text.length() - end)) < 0) {
1719d82f8a9a3869448e6d7d4b3fc962e34e33a1ba0eRaph Levien            throw new IndexOutOfBoundsException();
1720d82f8a9a3869448e6d7d4b3fc962e34e33a1ba0eRaph Levien        }
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (text instanceof String || text instanceof SpannedString ||
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            text instanceof SpannableString) {
17235c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            native_drawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
1724dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                    paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
1725f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        } else if (text instanceof GraphicsOperations) {
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((GraphicsOperations) text).drawText(this, start, end, x, y,
1727f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy                    paint);
1728f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        } else {
1729f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            char[] buf = TemporaryBuffer.obtain(end - start);
1730f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            TextUtils.getChars(text, start, end, buf, 0);
17315c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            native_drawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
1732dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                    paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
1733f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            TemporaryBuffer.recycle(buf);
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1735f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    }
1736f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
1737f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    /**
1738f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * Render a run of all LTR or all RTL text, with shaping. This does not run
1739f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * bidi on the provided text, but renders it as a uniform right-to-left or
1740f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * left-to-right run, as indicated by dir. Alignment of the text is as
1741f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * determined by the Paint's TextAlign value.
1742051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
1743f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param text the text to render
17440c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     * @param index the start of the text to render
17450c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     * @param count the count of chars to render
17460c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     * @param contextIndex the start of the context for shaping.  Must be
17470c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     *         no greater than index.
17480c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     * @param contextCount the number of characters in the context for shaping.
17490c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     *         ContexIndex + contextCount must be no less than index
17500c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     *         + count.
1751f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param x the x position at which to draw the text
1752f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param y the y position at which to draw the text
1753051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @param isRtl whether the run is in RTL direction
1754f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param paint the paint
1755f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @hide
1756f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     */
1757ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
1758051910b9f998030dacb8a0722588cc715813fde1Raph Levien            int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
1759f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
1760f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        if (text == null) {
1761f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            throw new NullPointerException("text is null");
1762f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        }
1763f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        if (paint == null) {
1764f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            throw new NullPointerException("paint is null");
1765f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        }
17660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        if ((index | count | text.length - index - count) < 0) {
1767f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            throw new IndexOutOfBoundsException();
1768f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        }
1769f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
17705c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawTextRun(mNativeCanvasWrapper, text, index, count,
1771dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                contextIndex, contextCount, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
1772f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    }
1773f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
1774f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt    /**
1775f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * Render a run of all LTR or all RTL text, with shaping. This does not run
1776f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * bidi on the provided text, but renders it as a uniform right-to-left or
1777f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * left-to-right run, as indicated by dir. Alignment of the text is as
1778f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * determined by the Paint's TextAlign value.
17790c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     *
1780f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param text the text to render
1781f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param start the start of the text to render. Data before this position
1782f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     *            can be used for shaping context.
1783f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param end the end of the text to render. Data at or after this
1784f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     *            position can be used for shaping context.
1785f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param x the x position at which to draw the text
1786f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param y the y position at which to draw the text
1787051910b9f998030dacb8a0722588cc715813fde1Raph Levien     * @param isRtl whether the run is in RTL direction
1788f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @param paint the paint
1789f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     * @hide
1790f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt     */
1791ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
1792051910b9f998030dacb8a0722588cc715813fde1Raph Levien            int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
1793f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
1794f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        if (text == null) {
1795f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            throw new NullPointerException("text is null");
1796f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        }
1797f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        if (paint == null) {
1798f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            throw new NullPointerException("paint is null");
1799f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        }
1800f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        if ((start | end | end - start | text.length() - end) < 0) {
1801f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt            throw new IndexOutOfBoundsException();
1802f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        }
1803f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
1804f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        if (text instanceof String || text instanceof SpannedString ||
1805f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt                text instanceof SpannableString) {
18065c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            native_drawTextRun(mNativeCanvasWrapper, text.toString(), start, end,
1807dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                    contextStart, contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
1808f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        } else if (text instanceof GraphicsOperations) {
18090c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            ((GraphicsOperations) text).drawTextRun(this, start, end,
1810051910b9f998030dacb8a0722588cc715813fde1Raph Levien                    contextStart, contextEnd, x, y, isRtl, paint);
1811f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt        } else {
18120c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            int contextLen = contextEnd - contextStart;
18130c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            int len = end - start;
18140c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            char[] buf = TemporaryBuffer.obtain(contextLen);
18150c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
18165c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            native_drawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
1817dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                    0, contextLen, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TemporaryBuffer.recycle(buf);
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text in the array, with each character's origin specified by
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the pos array.
1825051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
182662b6eaa7f3a8111311a7ee097f278eb55865a499Romain Guy     * This method does not support glyph composition and decomposition and
18273f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien     * should therefore not be used to render complex scripts. It also doesn't
18283f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien     * handle supplementary characters (eg emoji).
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text     The text to be drawn
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index    The index of the first character to draw
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count    The number of characters to draw, starting from index.
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pos      Array of [x,y] positions, used to position each
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 character
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint    The paint used for the text (e.g. color, size, style)
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1837f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy    @Deprecated
1838b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye    public void drawPosText(@NonNull char[] text, int index, int count,
1839b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye            @NonNull @Size(multiple=2) float[] pos,
1840ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            @NonNull Paint paint) {
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0 || index + count > text.length || count*2 > pos.length) {
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException();
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18443f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien        for (int i = 0; i < count; i++) {
18453f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien            drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
18463f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien        }
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text in the array, with each character's origin specified by
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the pos array.
1852051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
185362b6eaa7f3a8111311a7ee097f278eb55865a499Romain Guy     * This method does not support glyph composition and decomposition and
18543f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien     * should therefore not be used to render complex scripts. It also doesn't
18553f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien     * handle supplementary characters (eg emoji).
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text  The text to be drawn
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pos   Array of [x,y] positions, used to position each character
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint The paint used for the text (e.g. color, size, style)
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1861f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy    @Deprecated
1862b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye    public void drawPosText(@NonNull String text, @NonNull @Size(multiple=2) float[] pos,
1863b3ec733bb830f2d4425825d93f9ed95f284e9145Tor Norbye            @NonNull Paint paint) {
18643f0d6167227d6d2cdd85f7718d92db859b443e92Raph Levien        drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text, with origin at (x,y), using the specified paint, along
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the specified path. The paint's Align setting determins where along the
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * path to start the text.
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text     The text to be drawn
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path     The path the text should follow for its baseline
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hOffset  The distance along the path to add to the text's
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 starting position
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vOffset  The distance above(-) or below(+) the path to position
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the text
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint    The paint used for the text (e.g. color, size, style)
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1880ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
1881ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            float hOffset, float vOffset, @NonNull Paint paint) {
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0 || index + count > text.length) {
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18855c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        native_drawTextOnPath(mNativeCanvasWrapper, text, index, count,
1886f296dca95f09be9832b5dcc79717986525d2b6cbRomain Guy                path.ni(), hOffset, vOffset,
1887dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the text, with origin at (x,y), using the specified paint, along
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the specified path. The paint's Align setting determins where along the
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * path to start the text.
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text     The text to be drawn
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path     The path the text should follow for its baseline
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hOffset  The distance along the path to add to the text's
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 starting position
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vOffset  The distance above(-) or below(+) the path to position
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the text
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint    The paint used for the text (e.g. color, size, style)
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1903ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
1904ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese            float vOffset, @NonNull Paint paint) {
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (text.length() > 0) {
19065c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita            native_drawTextOnPath(mNativeCanvasWrapper, text, path.ni(), hOffset, vOffset,
1907dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger                    paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Save the canvas state, draw the picture, and restore the canvas state.
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This differs from picture.draw(canvas), which does not perform any
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * save/restore.
1915cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     *
1916cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * <p>
1917cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * <strong>Note:</strong> This forces the picture to internally call
1918cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * {@link Picture#endRecording} in order to prepare for playback.
1919051910b9f998030dacb8a0722588cc715813fde1Raph Levien     *
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param picture  The picture to be drawn
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1922ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPicture(@NonNull Picture picture) {
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        picture.endRecording();
1924667fe1039feae068d3333de8fb7115313f4a517bJonathan Dixon        int restoreCount = save();
1925667fe1039feae068d3333de8fb7115313f4a517bJonathan Dixon        picture.draw(this);
1926667fe1039feae068d3333de8fb7115313f4a517bJonathan Dixon        restoreToCount(restoreCount);
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1928051910b9f998030dacb8a0722588cc715813fde1Raph Levien
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the picture, stretched to fit into the dst rectangle.
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1932ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPicture(@NonNull Picture picture, @NonNull RectF dst) {
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        save();
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        translate(dst.left, dst.top);
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (picture.getWidth() > 0 && picture.getHeight() > 0) {
1936f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy            scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawPicture(picture);
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        restore();
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1941051910b9f998030dacb8a0722588cc715813fde1Raph Levien
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw the picture, stretched to fit into the dst rectangle.
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1945ff7215aa0cb28a4815126b056f34b2bd29e5c651Antonio Calabrese    public void drawPicture(@NonNull Picture picture, @NonNull Rect dst) {
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        save();
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        translate(dst.left, dst.top);
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (picture.getWidth() > 0 && picture.getHeight() > 0) {
1949f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy            scale((float) dst.width() / picture.getWidth(),
1950f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy                    (float) dst.height() / picture.getHeight());
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawPicture(picture);
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        restore();
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1955da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
1956da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    /**
1957ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov     * Releases the resources associated with this canvas.
1958ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov     *
1959ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov     * @hide
1960ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov     */
1961ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov    public void release() {
1962ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov        mFinalizer.dispose();
1963ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov    }
1964ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov
1965ff4adde5737be08d3e2d03fbe588c591d27d4a74Svetoslav Ganov    /**
1966163935113919a184122b8b3bd672ef08c8df65dcRomain Guy     * Free up as much memory as possible from private caches (e.g. fonts, images)
1967caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed     *
1968163935113919a184122b8b3bd672ef08c8df65dcRomain Guy     * @hide
1969caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed     */
1970caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed    public static native void freeCaches();
1971caf0df1b7f99736aed1a0b923ef278fc4fd0fccaMike Reed
197230ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio    /**
197330ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio     * Free up text layout caches
197430ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio     *
197530ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio     * @hide
197630ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio     */
197730ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio    public static native void freeTextLayoutCaches();
197830ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio
197936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long initRaster(long nativeBitmapOrZero);
19805c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita    private static native void native_setBitmap(long canvasHandle,
19815c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita                                                long bitmapHandle,
19825c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita                                                boolean copyState);
198395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native boolean native_isOpaque(long canvasHandle);
198495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native int native_getWidth(long canvasHandle);
198595d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native int native_getHeight(long canvasHandle);
198695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita
198795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native int native_save(long canvasHandle, int saveFlags);
198836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int native_saveLayer(long nativeCanvas, float l,
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               float t, float r, float b,
199036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               long nativePaint,
199136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               int layerFlags);
199236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int native_saveLayerAlpha(long nativeCanvas, float l,
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    float t, float r, float b,
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int alpha, int layerFlags);
19953891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik    private static native void native_restore(long canvasHandle, boolean tolerateUnderflow);
199695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_restoreToCount(long canvasHandle,
19973891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik                                                     int saveCount,
19983891f3ad598561d5a82c07795e1fee7f1d3612d1Chris Craik                                                     boolean tolerateUnderflow);
199995d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native int native_getSaveCount(long canvasHandle);
200095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita
200195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_translate(long canvasHandle,
200295d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                                float dx, float dy);
200395d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_scale(long canvasHandle,
200495d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                            float sx, float sy);
200595d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_rotate(long canvasHandle, float degrees);
200695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_skew(long canvasHandle,
200795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                           float sx, float sy);
200836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_concat(long nativeCanvas,
200936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                             long nativeMatrix);
201036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_setMatrix(long nativeCanvas,
201136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                long nativeMatrix);
201236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean native_clipRect(long nativeCanvas,
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  float left, float top,
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  float right, float bottom,
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  int regionOp);
201636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean native_clipPath(long nativeCanvas,
201736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                  long nativePath,
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  int regionOp);
201936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean native_clipRegion(long nativeCanvas,
202036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                    long nativeRegion,
20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int regionOp);
202236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeSetDrawFilter(long nativeCanvas,
202336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                   long nativeFilter);
202436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean native_getClipBounds(long nativeCanvas,
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                       Rect bounds);
202636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_getCTM(long nativeCanvas,
202736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                             long nativeMatrix);
202836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean native_quickReject(long nativeCanvas,
202936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                     long nativePath);
203036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean native_quickReject(long nativeCanvas,
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                     float left, float top,
2032ca79cf69d09efa0c327e9b1237d86a119aea5da7Derek Sollenberger                                                     float right, float bottom);
203336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawColor(long nativeCanvas, int color,
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                int mode);
203536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawPaint(long nativeCanvas,
203636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                long nativePaint);
203795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_drawPoint(long canvasHandle, float x, float y,
203895d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                                long paintHandle);
203995d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_drawPoints(long canvasHandle, float[] pts,
204095d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                                 int offset, int count,
204195d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                                 long paintHandle);
204236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawLine(long nativeCanvas, float startX,
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               float startY, float stopX,
204436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               float stopY, long nativePaint);
204595d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita    private static native void native_drawLines(long canvasHandle, float[] pts,
204695d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                                int offset, int count,
204795d49149cc7fff87a18449fa661454c1b5ddbd30Florin Malita                                                long paintHandle);
204836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawRect(long nativeCanvas, float left,
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               float top, float right,
205036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               float bottom,
205136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               long nativePaint);
205224609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    private static native void native_drawOval(long nativeCanvas, float left, float top,
205324609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese                                               float right, float bottom, long nativePaint);
205436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawCircle(long nativeCanvas, float cx,
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 float cy, float radius,
205636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                 long nativePaint);
205724609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese    private static native void native_drawArc(long nativeCanvas, float left, float top,
205824609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese                                              float right, float bottom,
205924609581330bc350f797179e3c1a59789c645ec2Antonio Calabrese                                              float startAngle, float sweep, boolean useCenter,
206036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                              long nativePaint);
206136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawRoundRect(long nativeCanvas,
20624d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik            float left, float top, float right, float bottom,
20634d1c1538e2422d0a5b19ad1cd2fb353ed6279a88Chris Craik            float rx, float ry, long nativePaint);
206436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawPath(long nativeCanvas,
206536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               long nativePath,
206636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               long nativePaint);
206736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private native void native_drawBitmap(long nativeCanvas, long nativeBitmap,
20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 float left, float top,
206936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                 long nativePaintOrZero,
20700d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                                                 int canvasDensity,
20710d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                                                 int screenDensity,
20720d221012ff5fd314711c00ed30e9b807b9c454c1Dianne Hackborn                                                 int bitmapDensity);
207336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private native void native_drawBitmap(long nativeCanvas, long nativeBitmap,
20748872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            float srcLeft, float srcTop, float srcRight, float srcBottom,
20758872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            float dstLeft, float dstTop, float dstRight, float dstBottom,
20768872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger            long nativePaintOrZero, int screenDensity, int bitmapDensity);
207736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawBitmap(long nativeCanvas, int[] colors,
20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                int offset, int stride, float x,
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 float y, int width, int height,
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 boolean hasAlpha,
208136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                 long nativePaintOrZero);
208236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeDrawBitmapMatrix(long nativeCanvas,
208336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                      long nativeBitmap,
208436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                      long nativeMatrix,
208536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                      long nativePaint);
208636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeDrawBitmapMesh(long nativeCanvas,
208736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                    long nativeBitmap,
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int meshWidth, int meshHeight,
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    float[] verts, int vertOffset,
209036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                    int[] colors, int colorOffset,
209136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                    long nativePaint);
209236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeDrawVertices(long nativeCanvas, int mode, int n,
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   float[] verts, int vertOffset, float[] texs, int texOffset,
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   int[] colors, int colorOffset, short[] indices,
209536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                   int indexOffset, int indexCount, long nativePaint);
209636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
209736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawText(long nativeCanvas, char[] text,
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               int index, int count, float x,
209936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               float y, int flags, long nativePaint,
210036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               long nativeTypeface);
210136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawText(long nativeCanvas, String text,
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               int start, int end, float x,
210336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               float y, int flags, long nativePaint,
210436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                               long nativeTypeface);
2105fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio
210636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawTextRun(long nativeCanvas, String text,
21070c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            int start, int end, int contextStart, int contextEnd,
2108051910b9f998030dacb8a0722588cc715813fde1Raph Levien            float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);
2109f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
211036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawTextRun(long nativeCanvas, char[] text,
21110c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            int start, int count, int contextStart, int contextCount,
2112051910b9f998030dacb8a0722588cc715813fde1Raph Levien            float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);
2113f47d7405bbcb25d7cdf89ebb059f41520fe9ab87Doug Felt
211436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawTextOnPath(long nativeCanvas,
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                     char[] text, int index,
211636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                     int count, long nativePath,
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                     float hOffset,
2118da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio                                                     float vOffset, int bidiFlags,
21199d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien                                                     long nativePaint, long nativeTypeface);
212036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void native_drawTextOnPath(long nativeCanvas,
212136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                     String text, long nativePath,
212236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                     float hOffset,
212336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                     float vOffset,
21249d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien                                                     int flags, long nativePaint, long nativeTypeface);
212536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void finalizer(long nativeCanvas);
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2127