GLES20Canvas.java revision 5c13d89c1332fcc499379b9064b891187b75ca32
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/*
2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright (C) 2010 The Android Open Source Project
3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License.
6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at
7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software
11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and
14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License.
15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
17e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guypackage android.view;
18e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
19e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Bitmap;
20e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Canvas;
21db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guyimport android.graphics.ColorFilter;
22e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.DrawFilter;
23e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Matrix;
24e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Paint;
25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Path;
26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Picture;
27e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.PorterDuff;
28e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Rect;
29e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.RectF;
30e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Region;
31d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guyimport android.graphics.Shader;
32a1db574036c9bc2d397b69f8200594027e1fff16Romain Guyimport android.graphics.TemporaryBuffer;
33a1db574036c9bc2d397b69f8200594027e1fff16Romain Guyimport android.text.GraphicsOperations;
34a1db574036c9bc2d397b69f8200594027e1fff16Romain Guyimport android.text.SpannableString;
35a1db574036c9bc2d397b69f8200594027e1fff16Romain Guyimport android.text.SpannedString;
36a1db574036c9bc2d397b69f8200594027e1fff16Romain Guyimport android.text.TextUtils;
375c13d89c1332fcc499379b9064b891187b75ca32Chet Haaseimport android.util.Finalizers;
385c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
395c13d89c1332fcc499379b9064b891187b75ca32Chet Haaseimport java.util.Collections;
405c13d89c1332fcc499379b9064b891187b75ca32Chet Haaseimport java.util.HashSet;
415c13d89c1332fcc499379b9064b891187b75ca32Chet Haaseimport java.util.Set;
42e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
43e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/**
44e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * An implementation of Canvas on top of OpenGL ES 2.0.
45e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
46b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guyclass GLES20Canvas extends HardwareCanvas {
47e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private final boolean mOpaque;
48fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    private int mRenderer;
49e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
50e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mWidth;
51e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mHeight;
52ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
53ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    private final float[] mPoint = new float[2];
54ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    private final float[] mLine = new float[4];
556926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
566926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    private final Rect mClipBounds = new Rect();
576926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
586926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    private DrawFilter mFilter;
59da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
60da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    private boolean mContextLocked;
61da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
62163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
63163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    // JNI
64163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
65163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
66163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static native boolean nIsAvailable();
67163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static boolean sIsAvailable = nIsAvailable();
68163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
69163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static boolean isAvailable() {
70163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return sIsAvailable;
71163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
72e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
73e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
74e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Constructors
75e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
76b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
77b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    GLES20Canvas(boolean translucent) {
78b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        this(false, translucent);
79b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    }
80e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
81b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    GLES20Canvas(boolean record, boolean translucent) {
82e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mOpaque = !translucent;
83e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
84b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        if (record) {
85b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy            mRenderer = nCreateDisplayListRenderer();
86b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        } else {
87b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy            mRenderer = nCreateRenderer();
88b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        }
89b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
90fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        if (mRenderer == 0) {
91fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy            throw new IllegalStateException("Could not create GLES20Canvas renderer");
925c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        } else {
935c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            new CanvasFinalizer(this);
94fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        }
95e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
96b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
97b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    private native int nCreateRenderer();
98b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    private native int nCreateDisplayListRenderer();
99b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
1005c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    private static native void nDestroyRenderer(int renderer);
1015c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1025c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    private static class CanvasFinalizer extends Finalizers.ReclaimableReference<GLES20Canvas> {
1035c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        private static final Set<CanvasFinalizer> sFinalizers = Collections.synchronizedSet(
1045c13d89c1332fcc499379b9064b891187b75ca32Chet Haase                new HashSet<CanvasFinalizer>());
1055c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1065c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        private int mRenderer;
1075c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1085c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        CanvasFinalizer(GLES20Canvas canvas) {
1095c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            super(canvas, Finalizers.getQueue());
1105c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            mRenderer = canvas.mRenderer;
1115c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            sFinalizers.add(this);
1125c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        }
1135c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
1145c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        @Override
1155c13d89c1332fcc499379b9064b891187b75ca32Chet Haase        public void reclaim() {
116e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            nDestroyRenderer(mRenderer);
1175c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            sFinalizers.remove(this);
118e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        }
119e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
120ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
121e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
122e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Canvas management
123e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
124e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
125e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
126e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean isOpaque() {
127e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mOpaque;
128e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
129e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
130e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
131e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getWidth() {
132e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mWidth;
133e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
134e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
135e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
136e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getHeight() {
137e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mHeight;
138e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
139e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
140e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
141e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Setup
142e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
143e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
144e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
145e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void setViewport(int width, int height) {
146e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mWidth = width;
147e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mHeight = height;
148e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
149e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        nSetViewport(mRenderer, width, height);
150e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
151e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
152e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private native void nSetViewport(int renderer, int width, int height);
153e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
154b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    @Override
155e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    void onPreDraw() {
1566b7bd24659fb175fe1f0e97c86c18969918b496aRomain Guy        nPrepare(mRenderer, mOpaque);
157e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
158b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
1596b7bd24659fb175fe1f0e97c86c18969918b496aRomain Guy    private native void nPrepare(int renderer, boolean opaque);
160e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
161b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    @Override
162b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    void onPostDraw() {
163b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy        nFinish(mRenderer);
164b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    }
165b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
166b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    private native void nFinish(int renderer);
167b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
168da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    @Override
169da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    public boolean acquireContext() {
170da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        if (!mContextLocked) {
171da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            nAcquireContext(mRenderer);
172da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            mContextLocked = true;
173da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        }
174da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        return mContextLocked;
175da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    }
176da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
177da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    private native void nAcquireContext(int renderer);
178da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
179da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    @Override
180da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    public void releaseContext() {
181da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        if (mContextLocked) {
182da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            nReleaseContext(mRenderer);
183da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            mContextLocked = false;
184da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        }
185da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    }
186da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
187da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    private native void nReleaseContext(int renderer);
188b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
189b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    ///////////////////////////////////////////////////////////////////////////
190b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Display list
191b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    ///////////////////////////////////////////////////////////////////////////
192b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
193b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    int getDisplayList() {
194b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        return nCreateDisplayList(mRenderer);
195b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    }
196b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
197b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    private native int nCreateDisplayList(int renderer);
198b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
1995c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    static void destroyDisplayList(int displayList) {
200b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        nDestroyDisplayList(displayList);
201b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    }
202b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
2035c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    private static native void nDestroyDisplayList(int displayList);
204b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
205b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    @Override
206b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    public void drawDisplayList(DisplayList displayList) {
207b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy        nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
208b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    }
209b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
210b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    private native void nDrawDisplayList(int renderer, int displayList);
211da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
212e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
213e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Clipping
214e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
215e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
216e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
217e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipPath(Path path) {
218e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
219e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
220e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
221e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
222e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipPath(Path path, Region.Op op) {
223e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
224e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
225e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
226e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
227e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(float left, float top, float right, float bottom) {
228079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
229e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
230bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
231079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    private native boolean nClipRect(int renderer, float left, float top,
232079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            float right, float bottom, int op);
233e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
234e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
235e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) {
236079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt);
237e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
238e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
239e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
240e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(int left, int top, int right, int bottom) {
241079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
242e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
243bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
244079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    private native boolean nClipRect(int renderer, int left, int top, int right, int bottom, int op);
245e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
246e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
247e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(Rect rect) {
248079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
249079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                Region.Op.INTERSECT.nativeInt);
250e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
251e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
252e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
253e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(Rect rect, Region.Op op) {
254079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
255e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
256e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
257e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
258e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(RectF rect) {
259079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
260079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                Region.Op.INTERSECT.nativeInt);
261e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
262e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
263e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
264e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRect(RectF rect, Region.Op op) {
265079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
266e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
267e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
268e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
269e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRegion(Region region) {
270e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
271e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
272e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
273e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
274e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean clipRegion(Region region, Region.Op op) {
275e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
276e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
277e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
278e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
279e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean getClipBounds(Rect bounds) {
2809d5316e3f56d138504565ff311145ac01621dff4Romain Guy        return nGetClipBounds(mRenderer, bounds);
281e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
282e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
2839d5316e3f56d138504565ff311145ac01621dff4Romain Guy    private native boolean nGetClipBounds(int renderer, Rect bounds);
2849d5316e3f56d138504565ff311145ac01621dff4Romain Guy
285e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
286e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
287c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt);
288e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
289c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
290c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    private native boolean nQuickReject(int renderer, float left, float top,
291c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy            float right, float bottom, int edge);
292e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
293e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
294e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean quickReject(Path path, EdgeType type) {
295bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        throw new UnsupportedOperationException();
296e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
297e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
298e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
299e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean quickReject(RectF rect, EdgeType type) {
300bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        return quickReject(rect.left, rect.top, rect.right, rect.bottom, type);
301e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
302e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
303e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
304e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Transformations
305e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
306e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
307e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
308e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void translate(float dx, float dy) {
309f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        nTranslate(mRenderer, dx, dy);
310e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
311f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
312f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    private native void nTranslate(int renderer, float dx, float dy);
313e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
314e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
315e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void skew(float sx, float sy) {
316e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
317e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
318e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
319e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
320e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void rotate(float degrees) {
321f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        nRotate(mRenderer, degrees);
322e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
323f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
324f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    private native void nRotate(int renderer, float degrees);
325e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
326e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
327e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void scale(float sx, float sy) {
328f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        nScale(mRenderer, sx, sy);
329e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
330e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
331f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    private native void nScale(int renderer, float sx, float sy);
332f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
333e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
334e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void setMatrix(Matrix matrix) {
335f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        nSetMatrix(mRenderer, matrix.native_instance);
336e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
337f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
338f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    private native void nSetMatrix(int renderer, int matrix);
339e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
340e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
34141030da16856c8869e1e51d4a0405432fa96614eRomain Guy    public int getNativeMatrix() {
34241030da16856c8869e1e51d4a0405432fa96614eRomain Guy        return nGetMatrix(mRenderer);
34341030da16856c8869e1e51d4a0405432fa96614eRomain Guy    }
34441030da16856c8869e1e51d4a0405432fa96614eRomain Guy
34541030da16856c8869e1e51d4a0405432fa96614eRomain Guy    private native int nGetMatrix(int renderer);
34641030da16856c8869e1e51d4a0405432fa96614eRomain Guy
34741030da16856c8869e1e51d4a0405432fa96614eRomain Guy    @Override
348f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    public void getMatrix(Matrix matrix) {
349f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        nGetMatrix(mRenderer, matrix.native_instance);
350e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
351f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
352f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    private native void nGetMatrix(int renderer, int matrix);
353e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
354e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
355e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void concat(Matrix matrix) {
356f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        nConcatMatrix(mRenderer, matrix.native_instance);
357e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
358e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
359f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    private native void nConcatMatrix(int renderer, int matrix);
360f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
361e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
362e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // State management
363e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
364e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
365e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
366e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int save() {
3678aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
368e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
369bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
370e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
371e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int save(int saveFlags) {
372bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        return nSave(mRenderer, saveFlags);
373e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
374e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
375bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    private native int nSave(int renderer, int flags);
376bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
377e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
378e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
379bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
380e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
381e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
382e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
383e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int saveLayer(float left, float top, float right, float bottom, Paint paint,
384e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            int saveFlags) {
385bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        int nativePaint = paint == null ? 0 : paint.mNativePaint;
386bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
387e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
388e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
389bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
390bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy            int paint, int saveFlags);
391bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
392e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
393e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
394bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
395bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy                alpha, saveFlags);
396e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
397e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
398e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
399e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
400e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            int saveFlags) {
401bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
402e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
403e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
404bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
405bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy            float bottom, int alpha, int saveFlags);
406bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
407e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
408e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void restore() {
409bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        nRestore(mRenderer);
410e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
411bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
412bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    private native void nRestore(int renderer);
413e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
414e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
415e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void restoreToCount(int saveCount) {
416bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        nRestoreToCount(mRenderer, saveCount);
417e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
418e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
419bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    private native void nRestoreToCount(int renderer, int saveCount);
420bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
421e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
422e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getSaveCount() {
423bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        return nGetSaveCount(mRenderer);
424e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
425bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
426bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    private native int nGetSaveCount(int renderer);
427e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
428e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
429e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Filtering
430e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
431e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
432e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
433e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void setDrawFilter(DrawFilter filter) {
4346926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        mFilter = filter;
435e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
436e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
437e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
438e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public DrawFilter getDrawFilter() {
4396926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        return mFilter;
440e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
441e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
442e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
443e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Drawing
444e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
445e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
446e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
447e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
448e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            Paint paint) {
449e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
450e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
451e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
452e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
453e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawARGB(int a, int r, int g, int b) {
45485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy        drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
455e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
456e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
457e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
458deba785f122a47915756ffd991f5540d952cf937Romain Guy    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
459d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing patches
460db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasColorFilter = paint != null && setupColorFilter(paint);
461deba785f122a47915756ffd991f5540d952cf937Romain Guy        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
462dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy        nDrawPatch(mRenderer, bitmap.mNativeBitmap, chunks, dst.left, dst.top,
463dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy                dst.right, dst.bottom, nativePaint);
464db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasColorFilter) nResetModifiers(mRenderer);
465deba785f122a47915756ffd991f5540d952cf937Romain Guy    }
466deba785f122a47915756ffd991f5540d952cf937Romain Guy
467deba785f122a47915756ffd991f5540d952cf937Romain Guy    private native void nDrawPatch(int renderer, int bitmap, byte[] chunks, float left, float top,
468dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy            float right, float bottom, int paint);
469deba785f122a47915756ffd991f5540d952cf937Romain Guy
470deba785f122a47915756ffd991f5540d952cf937Romain Guy    @Override
471e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
472d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing bitmaps
473db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasColorFilter = paint != null && setupColorFilter(paint);
474ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
475dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
476db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasColorFilter) nResetModifiers(mRenderer);
477e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
478e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
479dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy    private native void nDrawBitmap(int renderer, int bitmap, float left, float top, int paint);
480dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy
481e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
482e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
483d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing bitmaps
484db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasColorFilter = paint != null && setupColorFilter(paint);
485ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
486dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint);
487db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasColorFilter) nResetModifiers(mRenderer);
488e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
489e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
490dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy    private native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint);
491f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
492e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
493e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
494d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing bitmaps
495db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasColorFilter = paint != null && setupColorFilter(paint);
496ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
497694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy
498694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy        int left, top, right, bottom;
499694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy        if (src == null) {
500694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            left = top = 0;
501694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            right = bitmap.getWidth();
502694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            bottom = bitmap.getHeight();
503694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy        } else {
504694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            left = src.left;
505694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            right = src.right;
506694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            top = src.top;
507694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy            bottom = src.bottom;
508694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy        }
509694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy
510694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
511694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
512db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasColorFilter) nResetModifiers(mRenderer);
513e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
514e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
515e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
516e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
517d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing bitmaps
518db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasColorFilter = paint != null && setupColorFilter(paint);
519ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
520ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, src.left, src.top, src.right, src.bottom,
521694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
522db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasColorFilter) nResetModifiers(mRenderer);
523e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
524e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
525ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    private native void nDrawBitmap(int renderer, int bitmap,
526ce0537b80087a6225273040a987414b1dd081aa0Romain Guy            float srcLeft, float srcTop, float srcRight, float srcBottom,
527dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy            float left, float top, float right, float bottom, int paint);
528ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
529e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
530e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
531e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            int width, int height, boolean hasAlpha, Paint paint) {
532d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing bitmaps
533db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasColorFilter = paint != null && setupColorFilter(paint);
5346926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
5356926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config);
5366926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
5376926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        nDrawBitmap(mRenderer, b.mNativeBitmap, x, y, nativePaint);
5386926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        b.recycle();
539db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasColorFilter) nResetModifiers(mRenderer);
540e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
541e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
542e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
543e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmap(int[] colors, int offset, int stride, int x, int y,
544e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            int width, int height, boolean hasAlpha, Paint paint) {
545d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // Shaders are ignored when drawing bitmaps
546ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint);
547e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
548e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
549e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
550e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
551e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            int vertOffset, int[] colors, int colorOffset, Paint paint) {
5526926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        // TODO: Implement
553e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
554e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
555e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
556e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawCircle(float cx, float cy, float radius, Paint paint) {
557e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
558e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
559e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
560e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
561e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawColor(int color) {
56285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy        drawColor(color, PorterDuff.Mode.SRC_OVER);
563e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
564e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
565e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
566e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawColor(int color, PorterDuff.Mode mode) {
56785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy        nDrawColor(mRenderer, color, mode.nativeInt);
568e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
56985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
57085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    private native void nDrawColor(int renderer, int color, int mode);
571e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
572e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
573e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
574ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        mLine[0] = startX;
575ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        mLine[1] = startY;
576ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        mLine[2] = stopX;
577ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        mLine[3] = stopY;
578759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        drawLines(mLine, 0, 4, paint);
579e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
580e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
581e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
582e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawLines(float[] pts, int offset, int count, Paint paint) {
583759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        if ((offset | count) < 0 || offset + count > pts.length) {
584759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
585759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        }
586759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        boolean hasModifier = setupModifiers(paint);
587759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
588759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        if (hasModifier) nResetModifiers(mRenderer);
589e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
590e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
591759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    private native void nDrawLines(int renderer, float[] points, int offset, int count, int paint);
592759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
593e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
594e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawLines(float[] pts, Paint paint) {
595759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy        drawLines(pts, 0, pts.length, paint);
596e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
597e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
598e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
599e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawOval(RectF oval, Paint paint) {
600e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
601e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
602e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
603e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
604e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPaint(Paint paint) {
6056926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        final Rect r = mClipBounds;
6066926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        nGetClipBounds(mRenderer, r);
6076926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        drawRect(r.left, r.top, r.right, r.bottom, paint);
608e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
609e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
610e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
611e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPath(Path path, Paint paint) {
6127fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy        boolean hasModifier = setupModifiers(paint);
613a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy        if (path.isSimplePath) {
614a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy            if (path.rects != null) {
615a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy                nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
616a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy            }
617a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy        } else {
618a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy            nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
619a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy        }
6207fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy        if (hasModifier) nResetModifiers(mRenderer);
621e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
622e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
6237fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy    private native void nDrawPath(int renderer, int path, int paint);
624a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy    private native void nDrawRects(int renderer, int region, int paint);
6257fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy
626e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
627e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPicture(Picture picture) {
628e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
629e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
630e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
631e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
632e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPicture(Picture picture, Rect dst) {
633e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
634e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
635e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
636e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
637e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPicture(Picture picture, RectF dst) {
638e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
639e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
640e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
641e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
642e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPoint(float x, float y, Paint paint) {
643ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        mPoint[0] = x;
644ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        mPoint[1] = y;
645ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        drawPoints(mPoint, 0, 1, paint);
646e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
647e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
648e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
649e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
650e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        // TODO: Implement
651e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
652e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
653e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
654e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPoints(float[] pts, Paint paint) {
655ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        drawPoints(pts, 0, pts.length / 2, paint);
656e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
657e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
658e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
659e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
660e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
661e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
662e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
663e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
664e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPosText(String text, float[] pos, Paint paint) {
665e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
666e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
667e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
668e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
669e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
670db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasModifier = setupModifiers(paint);
671c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
672db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (hasModifier) nResetModifiers(mRenderer);
673e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
674e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
675c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    private native void nDrawRect(int renderer, float left, float top, float right, float bottom,
676c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy            int paint);
677c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
678e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
679e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawRect(Rect r, Paint paint) {
680c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        drawRect(r.left, r.top, r.right, r.bottom, paint);
681e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
682e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
683e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
684c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    public void drawRect(RectF r, Paint paint) {
685c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        drawRect(r.left, r.top, r.right, r.bottom, paint);
686e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
687e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
688e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
689e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawRGB(int r, int g, int b) {
69085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy        drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
691e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
692e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
693e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
694e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
695d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        // TODO: Implement
696e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
697e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
698e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
699e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
700a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy        if ((index | count | (index + count) | (text.length - index - count)) < 0) {
701a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy            throw new IndexOutOfBoundsException();
702a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy        }
70361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
704db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasModifier = setupModifiers(paint);
70561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        try {
70661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint);
70761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        } finally {
70861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (hasModifier) nResetModifiers(mRenderer);
70961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
710e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
711a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
712a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy    private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y,
713a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy            int bidiFlags, int paint);
714e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
715e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
716e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
717db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasModifier = setupModifiers(paint);
71861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        try {
71961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (text instanceof String || text instanceof SpannedString ||
72061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    text instanceof SpannableString) {
72161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
72261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                        paint.mNativePaint);
72361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            } else if (text instanceof GraphicsOperations) {
72461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                ((GraphicsOperations) text).drawText(this, start, end, x, y,
72561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                                                         paint);
72661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            } else {
72761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                char[] buf = TemporaryBuffer.obtain(end - start);
72861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                TextUtils.getChars(text, start, end, buf, 0);
72961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint);
73061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                TemporaryBuffer.recycle(buf);
73161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            }
73261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        } finally {
73361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (hasModifier) nResetModifiers(mRenderer);
734a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy        }
735e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
736e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
737e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
738e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
739a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy        if ((start | end | (end - start) | (text.length() - end)) < 0) {
740a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy            throw new IndexOutOfBoundsException();
741a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy        }
74261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
743db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasModifier = setupModifiers(paint);
74461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        try {
74561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint);
74661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        } finally {
74761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (hasModifier) nResetModifiers(mRenderer);
74861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
749e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
750e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
751a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy    private native void nDrawText(int renderer, String text, int start, int end, float x, float y,
752a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy            int bidiFlags, int paint);
753a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
754e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
755e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawText(String text, float x, float y, Paint paint) {
756db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasModifier = setupModifiers(paint);
75761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        try {
75861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags,
75961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    paint.mNativePaint);
76061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        } finally {
76161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (hasModifier) nResetModifiers(mRenderer);
76261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
763e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
764e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
765e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
766e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
767e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            float vOffset, Paint paint) {
768e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
769e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
770e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
771e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
772e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
773e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        throw new UnsupportedOperationException();
774e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
775e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
776e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
777e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
778e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            float x, float y, int dir, Paint paint) {
77961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        if ((index | count | text.length - index - count) < 0) {
78061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            throw new IndexOutOfBoundsException();
78161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
78261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) {
78361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            throw new IllegalArgumentException("Unknown direction: " + dir);
78461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
78561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
78661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        boolean hasModifier = setupModifiers(paint);
78761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        try {
78861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir,
78961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    paint.mNativePaint);
79061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        } finally {
79161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (hasModifier) nResetModifiers(mRenderer);
79261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
793e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
794e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
79561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    private native void nDrawTextRun(int renderer, char[] text, int index, int count,
79661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            int contextIndex, int contextCount, float x, float y, int dir, int nativePaint);
79761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
798e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
799e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
800e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            float x, float y, int dir, Paint paint) {
80161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        if ((start | end | end - start | text.length() - end) < 0) {
80261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            throw new IndexOutOfBoundsException();
80361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
80461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
80561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        boolean hasModifier = setupModifiers(paint);
80661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        try {
80761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            int flags = dir == 0 ? 0 : 1;
80861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (text instanceof String || text instanceof SpannedString ||
80961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                    text instanceof SpannableString) {
81061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
81161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                        contextEnd, x, y, flags, paint.mNativePaint);
81261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            } else if (text instanceof GraphicsOperations) {
81361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                ((GraphicsOperations) text).drawTextRun(this, start, end,
81461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                        contextStart, contextEnd, x, y, flags, paint);
81561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            } else {
81661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                int contextLen = contextEnd - contextStart;
81761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                int len = end - start;
81861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                char[] buf = TemporaryBuffer.obtain(contextLen);
81961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
82061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
82161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                        x, y, flags, paint.mNativePaint);
82261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy                TemporaryBuffer.recycle(buf);
82361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            }
82461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        } finally {
82561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            if (hasModifier) nResetModifiers(mRenderer);
82661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        }
827e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
828e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
82961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    private native void nDrawTextRun(int renderer, String text, int start, int end,
83061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            int contextStart, int contextEnd, float x, float y, int flags, int nativePaint);
83161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
832e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
833e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
834e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
835e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy            int indexOffset, int indexCount, Paint paint) {
8366926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        // TODO: Implement
837e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
838d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy
839db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    private boolean setupModifiers(Paint paint) {
840db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        boolean hasModifier = false;
841db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
8421e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        if (paint.hasShadow) {
8431e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
8441e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy                    paint.shadowColor);
8451e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            hasModifier = true;
8461e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        }
8471e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
848d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        final Shader shader = paint.getShader();
849d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        if (shader != null) {
85006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy            nSetupShader(mRenderer, shader.native_shader);
851db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy            hasModifier = true;
852db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        }
853db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
854db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        final ColorFilter filter = paint.getColorFilter();
855db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (filter != null) {
856db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
857db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy            hasModifier = true;
858db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        }
859db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
860db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        return hasModifier;
861db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    }
8621e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
863db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    private boolean setupColorFilter(Paint paint) {
864db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        final ColorFilter filter = paint.getColorFilter();
865db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        if (filter != null) {
866db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
86706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy            return true;
868d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy        }
869db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        return false;
870d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    }
871db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
87206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy    private native void nSetupShader(int renderer, int shader);
873db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    private native void nSetupColorFilter(int renderer, int colorFilter);
8741e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color);
8751e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
876db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    private native void nResetModifiers(int renderer);
877e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
878