Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.view; |
| 18 | |
| 19 | import android.graphics.Bitmap; |
| 20 | import android.graphics.Canvas; |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 21 | import android.graphics.ColorFilter; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 22 | import android.graphics.DrawFilter; |
| 23 | import android.graphics.Matrix; |
| 24 | import android.graphics.Paint; |
| 25 | import android.graphics.Path; |
| 26 | import android.graphics.Picture; |
| 27 | import android.graphics.PorterDuff; |
| 28 | import android.graphics.Rect; |
| 29 | import android.graphics.RectF; |
| 30 | import android.graphics.Region; |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 31 | import android.graphics.Shader; |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 32 | import android.graphics.TemporaryBuffer; |
| 33 | import android.text.GraphicsOperations; |
| 34 | import android.text.SpannableString; |
| 35 | import android.text.SpannedString; |
| 36 | import android.text.TextUtils; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 37 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 38 | /** |
| 39 | * An implementation of Canvas on top of OpenGL ES 2.0. |
| 40 | */ |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 41 | class GLES20Canvas extends HardwareCanvas { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 42 | // Must match modifiers used in the JNI layer |
| 43 | private static final int MODIFIER_NONE = 0; |
| 44 | private static final int MODIFIER_SHADOW = 1; |
| 45 | private static final int MODIFIER_SHADER = 2; |
| 46 | private static final int MODIFIER_COLOR_FILTER = 4; |
| 47 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 48 | private final boolean mOpaque; |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame] | 49 | private int mRenderer; |
Patrick Dubroy | f890fab | 2010-12-19 16:47:17 -0800 | [diff] [blame] | 50 | |
| 51 | // The native renderer will be destroyed when this object dies. |
| 52 | // DO NOT overwrite this reference once it is set. |
| 53 | private CanvasFinalizer mFinalizer; |
| 54 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 55 | private int mWidth; |
| 56 | private int mHeight; |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 57 | |
| 58 | private final float[] mPoint = new float[2]; |
| 59 | private final float[] mLine = new float[4]; |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 60 | |
| 61 | private final Rect mClipBounds = new Rect(); |
| 62 | |
| 63 | private DrawFilter mFilter; |
Romain Guy | da8532c | 2010-08-31 11:50:35 -0700 | [diff] [blame] | 64 | |
Romain Guy | 1639351 | 2010-08-08 00:14:31 -0700 | [diff] [blame] | 65 | /////////////////////////////////////////////////////////////////////////// |
| 66 | // JNI |
| 67 | /////////////////////////////////////////////////////////////////////////// |
| 68 | |
| 69 | private static native boolean nIsAvailable(); |
| 70 | private static boolean sIsAvailable = nIsAvailable(); |
| 71 | |
| 72 | static boolean isAvailable() { |
| 73 | return sIsAvailable; |
| 74 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 75 | |
| 76 | /////////////////////////////////////////////////////////////////////////// |
| 77 | // Constructors |
| 78 | /////////////////////////////////////////////////////////////////////////// |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 79 | |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 80 | /** |
| 81 | * Creates a canvas to render directly on screen. |
| 82 | */ |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 83 | GLES20Canvas(boolean translucent) { |
| 84 | this(false, translucent); |
| 85 | } |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 86 | |
| 87 | /** |
| 88 | * Creates a canvas to render into an FBO. |
| 89 | */ |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 90 | GLES20Canvas(int layer, boolean translucent) { |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 91 | mOpaque = !translucent; |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 92 | mRenderer = nCreateLayerRenderer(layer); |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 93 | setupFinalizer(); |
| 94 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 95 | |
Patrick Dubroy | f890fab | 2010-12-19 16:47:17 -0800 | [diff] [blame] | 96 | protected GLES20Canvas(boolean record, boolean translucent) { |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 97 | mOpaque = !translucent; |
| 98 | |
Chet Haase | 9e90a99 | 2011-01-04 16:23:21 -0800 | [diff] [blame] | 99 | setupRenderer(record); |
| 100 | } |
| 101 | |
| 102 | protected void setupRenderer(boolean record) { |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 103 | if (record) { |
Chet Haase | 5977baa | 2011-01-05 18:01:22 -0800 | [diff] [blame] | 104 | mRenderer = nGetDisplayListRenderer(mRenderer); |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 105 | } else { |
| 106 | mRenderer = nCreateRenderer(); |
| 107 | } |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 108 | |
| 109 | setupFinalizer(); |
| 110 | } |
| 111 | |
| 112 | private void setupFinalizer() { |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame] | 113 | if (mRenderer == 0) { |
| 114 | throw new IllegalStateException("Could not create GLES20Canvas renderer"); |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 115 | } else { |
Chet Haase | 5977baa | 2011-01-05 18:01:22 -0800 | [diff] [blame] | 116 | mFinalizer = CanvasFinalizer.getFinalizer(mFinalizer, mRenderer); |
Romain Guy | fb8b763 | 2010-08-23 21:05:08 -0700 | [diff] [blame] | 117 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 118 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 119 | |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 120 | private static native int nCreateRenderer(); |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 121 | private static native int nCreateLayerRenderer(int layer); |
Chet Haase | 5977baa | 2011-01-05 18:01:22 -0800 | [diff] [blame] | 122 | private static native int nGetDisplayListRenderer(int renderer); |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 123 | private static native void nDestroyRenderer(int renderer); |
| 124 | |
Patrick Dubroy | f890fab | 2010-12-19 16:47:17 -0800 | [diff] [blame] | 125 | private static class CanvasFinalizer { |
Chet Haase | 9e90a99 | 2011-01-04 16:23:21 -0800 | [diff] [blame] | 126 | int mRenderer; |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 127 | |
Chet Haase | 5977baa | 2011-01-05 18:01:22 -0800 | [diff] [blame] | 128 | // Factory method returns new instance if old one is null, or old instance |
| 129 | // otherwise, destroying native renderer along the way as necessary |
| 130 | static CanvasFinalizer getFinalizer(CanvasFinalizer oldFinalizer, int renderer) { |
| 131 | if (oldFinalizer == null) { |
| 132 | return new CanvasFinalizer(renderer); |
| 133 | } |
| 134 | oldFinalizer.replaceNativeObject(renderer); |
| 135 | return oldFinalizer; |
| 136 | } |
| 137 | |
| 138 | private CanvasFinalizer(int renderer) { |
Patrick Dubroy | f890fab | 2010-12-19 16:47:17 -0800 | [diff] [blame] | 139 | mRenderer = renderer; |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 140 | } |
| 141 | |
Chet Haase | 5977baa | 2011-01-05 18:01:22 -0800 | [diff] [blame] | 142 | private void replaceNativeObject(int newRenderer) { |
| 143 | if (mRenderer != 0 && newRenderer != mRenderer) { |
Chet Haase | 9e90a99 | 2011-01-04 16:23:21 -0800 | [diff] [blame] | 144 | nDestroyRenderer(mRenderer); |
| 145 | } |
| 146 | mRenderer = newRenderer; |
| 147 | } |
| 148 | |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 149 | @Override |
Patrick Dubroy | f890fab | 2010-12-19 16:47:17 -0800 | [diff] [blame] | 150 | protected void finalize() throws Throwable { |
Romain Guy | 171c592 | 2011-01-06 10:04:23 -0800 | [diff] [blame] | 151 | try { |
| 152 | replaceNativeObject(0); |
| 153 | } finally { |
| 154 | super.finalize(); |
| 155 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 156 | } |
| 157 | } |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 158 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 159 | /////////////////////////////////////////////////////////////////////////// |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 160 | // Hardware layers |
| 161 | /////////////////////////////////////////////////////////////////////////// |
| 162 | |
Romain Guy | aa6c24c | 2011-04-28 18:40:04 -0700 | [diff] [blame] | 163 | static native int nCreateTextureLayer(int[] layerInfo); |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 164 | static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo); |
| 165 | static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo); |
Romain Guy | 8f0095c | 2011-05-02 17:24:22 -0700 | [diff] [blame] | 166 | static native void nUpdateTextureLayer(int layerId, int width, int height, int surface); |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 167 | static native void nDestroyLayer(int layerId); |
| 168 | static native void nDestroyLayerDeferred(int layerId); |
Romain Guy | 57066eb | 2011-01-12 12:53:32 -0800 | [diff] [blame] | 169 | |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 170 | /////////////////////////////////////////////////////////////////////////// |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 171 | // Canvas management |
| 172 | /////////////////////////////////////////////////////////////////////////// |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 173 | |
| 174 | @Override |
| 175 | public boolean isOpaque() { |
| 176 | return mOpaque; |
| 177 | } |
| 178 | |
| 179 | @Override |
| 180 | public int getWidth() { |
| 181 | return mWidth; |
| 182 | } |
| 183 | |
| 184 | @Override |
| 185 | public int getHeight() { |
| 186 | return mHeight; |
| 187 | } |
| 188 | |
| 189 | /////////////////////////////////////////////////////////////////////////// |
| 190 | // Setup |
| 191 | /////////////////////////////////////////////////////////////////////////// |
| 192 | |
| 193 | @Override |
| 194 | public void setViewport(int width, int height) { |
| 195 | mWidth = width; |
| 196 | mHeight = height; |
| 197 | |
| 198 | nSetViewport(mRenderer, width, height); |
| 199 | } |
| 200 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 201 | private static native void nSetViewport(int renderer, int width, int height); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 202 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 203 | /** |
| 204 | * @hide |
| 205 | */ |
| 206 | public static boolean preserveBackBuffer() { |
| 207 | return nPreserveBackBuffer(); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 208 | } |
Romain Guy | b025b9c | 2010-09-16 14:16:48 -0700 | [diff] [blame] | 209 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 210 | private static native boolean nPreserveBackBuffer(); |
| 211 | |
| 212 | @Override |
| 213 | void onPreDraw(Rect dirty) { |
| 214 | if (dirty != null) { |
| 215 | nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, mOpaque); |
| 216 | } else { |
| 217 | nPrepare(mRenderer, mOpaque); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | private static native void nPrepare(int renderer, boolean opaque); |
| 222 | private static native void nPrepareDirty(int renderer, int left, int top, int right, int bottom, |
| 223 | boolean opaque); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 224 | |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 225 | @Override |
Romain Guy | b025b9c | 2010-09-16 14:16:48 -0700 | [diff] [blame] | 226 | void onPostDraw() { |
| 227 | nFinish(mRenderer); |
| 228 | } |
| 229 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 230 | private static native void nFinish(int renderer); |
Romain Guy | b025b9c | 2010-09-16 14:16:48 -0700 | [diff] [blame] | 231 | |
Romain Guy | da8532c | 2010-08-31 11:50:35 -0700 | [diff] [blame] | 232 | @Override |
Chet Haase | daf98e9 | 2011-01-10 14:10:36 -0800 | [diff] [blame] | 233 | public boolean callDrawGLFunction(int drawGLFunction) { |
| 234 | return nCallDrawGLFunction(mRenderer, drawGLFunction); |
| 235 | } |
| 236 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 237 | private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction); |
Chet Haase | daf98e9 | 2011-01-10 14:10:36 -0800 | [diff] [blame] | 238 | |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 239 | /////////////////////////////////////////////////////////////////////////// |
| 240 | // Display list |
| 241 | /////////////////////////////////////////////////////////////////////////// |
| 242 | |
| 243 | int getDisplayList() { |
Chet Haase | 5977baa | 2011-01-05 18:01:22 -0800 | [diff] [blame] | 244 | return nGetDisplayList(mRenderer); |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 245 | } |
| 246 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 247 | private static native int nGetDisplayList(int renderer); |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 248 | |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 249 | static void destroyDisplayList(int displayList) { |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 250 | nDestroyDisplayList(displayList); |
| 251 | } |
| 252 | |
Chet Haase | 5c13d89 | 2010-10-08 08:37:55 -0700 | [diff] [blame] | 253 | private static native void nDestroyDisplayList(int displayList); |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 254 | |
| 255 | @Override |
Romain Guy | 7b5b6ab | 2011-03-14 18:05:08 -0700 | [diff] [blame] | 256 | public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) { |
Romain Guy | cabfcc1 | 2011-03-07 18:06:46 -0800 | [diff] [blame] | 257 | return nDrawDisplayList(mRenderer, |
Romain Guy | 7b5b6ab | 2011-03-14 18:05:08 -0700 | [diff] [blame] | 258 | ((GLES20DisplayList) displayList).mNativeDisplayList, width, height, dirty); |
Romain Guy | b051e89 | 2010-09-28 19:09:36 -0700 | [diff] [blame] | 259 | } |
| 260 | |
Romain Guy | 7b5b6ab | 2011-03-14 18:05:08 -0700 | [diff] [blame] | 261 | private static native boolean nDrawDisplayList(int renderer, int displayList, |
| 262 | int width, int height, Rect dirty); |
Romain Guy | da8532c | 2010-08-31 11:50:35 -0700 | [diff] [blame] | 263 | |
Chet Haase | ed30fd8 | 2011-04-22 16:18:45 -0700 | [diff] [blame] | 264 | @Override |
| 265 | void outputDisplayList(DisplayList displayList) { |
| 266 | nOutputDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList); |
| 267 | } |
| 268 | |
| 269 | private static native void nOutputDisplayList(int renderer, int displayList); |
| 270 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 271 | /////////////////////////////////////////////////////////////////////////// |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 272 | // Hardware layer |
| 273 | /////////////////////////////////////////////////////////////////////////// |
| 274 | |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 275 | void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) { |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 276 | final GLES20Layer glLayer = (GLES20Layer) layer; |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 277 | int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 278 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Romain Guy | ada830f | 2011-01-13 12:13:20 -0800 | [diff] [blame] | 279 | nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 280 | if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 281 | } |
| 282 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 283 | private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint); |
Romain Guy | aa6c24c | 2011-04-28 18:40:04 -0700 | [diff] [blame] | 284 | |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 285 | void interrupt() { |
| 286 | nInterrupt(mRenderer); |
| 287 | } |
| 288 | |
| 289 | void resume() { |
| 290 | nResume(mRenderer); |
| 291 | } |
| 292 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 293 | private static native void nInterrupt(int renderer); |
| 294 | private static native void nResume(int renderer); |
Romain Guy | 6c319ca | 2011-01-11 14:29:25 -0800 | [diff] [blame] | 295 | |
| 296 | /////////////////////////////////////////////////////////////////////////// |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 297 | // Clipping |
| 298 | /////////////////////////////////////////////////////////////////////////// |
| 299 | |
| 300 | @Override |
| 301 | public boolean clipPath(Path path) { |
| 302 | throw new UnsupportedOperationException(); |
| 303 | } |
| 304 | |
| 305 | @Override |
| 306 | public boolean clipPath(Path path, Region.Op op) { |
| 307 | throw new UnsupportedOperationException(); |
| 308 | } |
| 309 | |
| 310 | @Override |
| 311 | public boolean clipRect(float left, float top, float right, float bottom) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 312 | return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 313 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 314 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 315 | private static native boolean nClipRect(int renderer, float left, float top, |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 316 | float right, float bottom, int op); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 317 | |
| 318 | @Override |
| 319 | public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 320 | return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 321 | } |
| 322 | |
| 323 | @Override |
| 324 | public boolean clipRect(int left, int top, int right, int bottom) { |
Chet Haase | daf98e9 | 2011-01-10 14:10:36 -0800 | [diff] [blame] | 325 | return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 326 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 327 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 328 | private static native boolean nClipRect(int renderer, int left, int top, int right, int bottom, |
| 329 | int op); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 330 | |
| 331 | @Override |
| 332 | public boolean clipRect(Rect rect) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 333 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, |
| 334 | Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 335 | } |
| 336 | |
| 337 | @Override |
| 338 | public boolean clipRect(Rect rect, Region.Op op) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 339 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 340 | } |
| 341 | |
| 342 | @Override |
| 343 | public boolean clipRect(RectF rect) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 344 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, |
| 345 | Region.Op.INTERSECT.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 346 | } |
| 347 | |
| 348 | @Override |
| 349 | public boolean clipRect(RectF rect, Region.Op op) { |
Romain Guy | 079ba2c | 2010-07-16 14:12:24 -0700 | [diff] [blame] | 350 | return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 351 | } |
| 352 | |
| 353 | @Override |
| 354 | public boolean clipRegion(Region region) { |
| 355 | throw new UnsupportedOperationException(); |
| 356 | } |
| 357 | |
| 358 | @Override |
| 359 | public boolean clipRegion(Region region, Region.Op op) { |
| 360 | throw new UnsupportedOperationException(); |
| 361 | } |
| 362 | |
| 363 | @Override |
| 364 | public boolean getClipBounds(Rect bounds) { |
Romain Guy | 9d5316e | 2010-06-24 19:30:36 -0700 | [diff] [blame] | 365 | return nGetClipBounds(mRenderer, bounds); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 366 | } |
| 367 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 368 | private static native boolean nGetClipBounds(int renderer, Rect bounds); |
Romain Guy | 9d5316e | 2010-06-24 19:30:36 -0700 | [diff] [blame] | 369 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 370 | @Override |
| 371 | public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 372 | return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 373 | } |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 374 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 375 | private static native boolean nQuickReject(int renderer, float left, float top, |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 376 | float right, float bottom, int edge); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 377 | |
| 378 | @Override |
| 379 | public boolean quickReject(Path path, EdgeType type) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 380 | throw new UnsupportedOperationException(); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 381 | } |
| 382 | |
| 383 | @Override |
| 384 | public boolean quickReject(RectF rect, EdgeType type) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 385 | return quickReject(rect.left, rect.top, rect.right, rect.bottom, type); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 386 | } |
| 387 | |
| 388 | /////////////////////////////////////////////////////////////////////////// |
| 389 | // Transformations |
| 390 | /////////////////////////////////////////////////////////////////////////// |
| 391 | |
| 392 | @Override |
| 393 | public void translate(float dx, float dy) { |
Romain Guy | 807daf7 | 2011-01-18 11:19:19 -0800 | [diff] [blame] | 394 | if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 395 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 396 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 397 | private static native void nTranslate(int renderer, float dx, float dy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 398 | |
| 399 | @Override |
| 400 | public void skew(float sx, float sy) { |
Romain Guy | 807daf7 | 2011-01-18 11:19:19 -0800 | [diff] [blame] | 401 | nSkew(mRenderer, sx, sy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 402 | } |
| 403 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 404 | private static native void nSkew(int renderer, float sx, float sy); |
Romain Guy | 807daf7 | 2011-01-18 11:19:19 -0800 | [diff] [blame] | 405 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 406 | @Override |
| 407 | public void rotate(float degrees) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 408 | nRotate(mRenderer, degrees); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 409 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 410 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 411 | private static native void nRotate(int renderer, float degrees); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 412 | |
| 413 | @Override |
| 414 | public void scale(float sx, float sy) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 415 | nScale(mRenderer, sx, sy); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 416 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 417 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 418 | private static native void nScale(int renderer, float sx, float sy); |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 419 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 420 | @Override |
| 421 | public void setMatrix(Matrix matrix) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 422 | nSetMatrix(mRenderer, matrix.native_instance); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 423 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 424 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 425 | private static native void nSetMatrix(int renderer, int matrix); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 426 | |
| 427 | @Override |
Romain Guy | 41030da | 2010-10-13 13:40:37 -0700 | [diff] [blame] | 428 | public int getNativeMatrix() { |
| 429 | return nGetMatrix(mRenderer); |
| 430 | } |
| 431 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 432 | private static native int nGetMatrix(int renderer); |
Romain Guy | 41030da | 2010-10-13 13:40:37 -0700 | [diff] [blame] | 433 | |
| 434 | @Override |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 435 | public void getMatrix(Matrix matrix) { |
| 436 | nGetMatrix(mRenderer, matrix.native_instance); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 437 | } |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 438 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 439 | private static native void nGetMatrix(int renderer, int matrix); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 440 | |
| 441 | @Override |
| 442 | public void concat(Matrix matrix) { |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 443 | nConcatMatrix(mRenderer, matrix.native_instance); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 444 | } |
| 445 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 446 | private static native void nConcatMatrix(int renderer, int matrix); |
Romain Guy | f6a11b8 | 2010-06-23 17:47:49 -0700 | [diff] [blame] | 447 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 448 | /////////////////////////////////////////////////////////////////////////// |
| 449 | // State management |
| 450 | /////////////////////////////////////////////////////////////////////////// |
| 451 | |
| 452 | @Override |
| 453 | public int save() { |
Romain Guy | 8aef54f | 2010-09-01 15:13:49 -0700 | [diff] [blame] | 454 | return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 455 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 456 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 457 | @Override |
| 458 | public int save(int saveFlags) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 459 | return nSave(mRenderer, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 460 | } |
| 461 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 462 | private static native int nSave(int renderer, int flags); |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 463 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 464 | @Override |
| 465 | public int saveLayer(RectF bounds, Paint paint, int saveFlags) { |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 466 | return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 467 | } |
| 468 | |
| 469 | @Override |
| 470 | public int saveLayer(float left, float top, float right, float bottom, Paint paint, |
| 471 | int saveFlags) { |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 472 | if (left < right && top < bottom) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 473 | int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 474 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
| 475 | int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 476 | if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 477 | return count; |
| 478 | } |
| 479 | return save(saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 480 | } |
| 481 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 482 | private static native int nSaveLayer(int renderer, float left, float top, |
| 483 | float right, float bottom, int paint, int saveFlags); |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 484 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 485 | @Override |
| 486 | public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 487 | return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, |
| 488 | alpha, saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 489 | } |
| 490 | |
| 491 | @Override |
| 492 | public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, |
| 493 | int saveFlags) { |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 494 | if (left < right && top < bottom) { |
| 495 | return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags); |
| 496 | } |
| 497 | return save(saveFlags); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 498 | } |
| 499 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 500 | private static native int nSaveLayerAlpha(int renderer, float left, float top, float right, |
Romain Guy | bd6b79b | 2010-06-26 00:13:53 -0700 | [diff] [blame] | 501 | float bottom, int alpha, int saveFlags); |
| 502 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 503 | @Override |
| 504 | public void restore() { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 505 | nRestore(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 506 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 507 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 508 | private static native void nRestore(int renderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 509 | |
| 510 | @Override |
| 511 | public void restoreToCount(int saveCount) { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 512 | nRestoreToCount(mRenderer, saveCount); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 513 | } |
| 514 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 515 | private static native void nRestoreToCount(int renderer, int saveCount); |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 516 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 517 | @Override |
| 518 | public int getSaveCount() { |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 519 | return nGetSaveCount(mRenderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 520 | } |
Romain Guy | bb9524b | 2010-06-22 18:56:38 -0700 | [diff] [blame] | 521 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 522 | private static native int nGetSaveCount(int renderer); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 523 | |
| 524 | /////////////////////////////////////////////////////////////////////////// |
| 525 | // Filtering |
| 526 | /////////////////////////////////////////////////////////////////////////// |
| 527 | |
| 528 | @Override |
| 529 | public void setDrawFilter(DrawFilter filter) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 530 | mFilter = filter; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 531 | } |
| 532 | |
| 533 | @Override |
| 534 | public DrawFilter getDrawFilter() { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 535 | return mFilter; |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 536 | } |
| 537 | |
| 538 | /////////////////////////////////////////////////////////////////////////// |
| 539 | // Drawing |
| 540 | /////////////////////////////////////////////////////////////////////////// |
| 541 | |
| 542 | @Override |
| 543 | public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, |
| 544 | Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 545 | int modifiers = setupModifiers(paint); |
Romain Guy | 8b2f526 | 2011-01-23 16:15:02 -0800 | [diff] [blame] | 546 | nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, |
| 547 | useCenter, paint.mNativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 548 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 549 | } |
| 550 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 551 | private static native void nDrawArc(int renderer, float left, float top, |
| 552 | float right, float bottom, float startAngle, float sweepAngle, |
| 553 | boolean useCenter, int paint); |
Romain Guy | 8b2f526 | 2011-01-23 16:15:02 -0800 | [diff] [blame] | 554 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 555 | @Override |
| 556 | public void drawARGB(int a, int r, int g, int b) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 557 | drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 558 | } |
| 559 | |
| 560 | @Override |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 561 | public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 562 | // Shaders are ignored when drawing patches |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 563 | int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 564 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 565 | nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks, |
| 566 | dst.left, dst.top, dst.right, dst.bottom, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 567 | if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 568 | } |
| 569 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 570 | private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks, |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 571 | float left, float top, float right, float bottom, int paint); |
Romain Guy | deba785 | 2010-07-07 17:54:48 -0700 | [diff] [blame] | 572 | |
| 573 | @Override |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 574 | public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 575 | // Shaders are ignored when drawing bitmaps |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 576 | int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 577 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 578 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 579 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 580 | } |
| 581 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 582 | private static native void nDrawBitmap( |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 583 | int renderer, int bitmap, byte[] buffer, float left, float top, int paint); |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 584 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 585 | @Override |
| 586 | public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 587 | // Shaders are ignored when drawing bitmaps |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 588 | int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 589 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 590 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, |
| 591 | matrix.native_instance, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 592 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 593 | } |
| 594 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 595 | private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff, |
| 596 | int matrix, int paint); |
Romain Guy | f86ef57 | 2010-07-01 11:05:42 -0700 | [diff] [blame] | 597 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 598 | @Override |
| 599 | public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 600 | // Shaders are ignored when drawing bitmaps |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 601 | int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 602 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Romain Guy | 694b519 | 2010-07-21 21:33:20 -0700 | [diff] [blame] | 603 | |
| 604 | int left, top, right, bottom; |
| 605 | if (src == null) { |
| 606 | left = top = 0; |
| 607 | right = bitmap.getWidth(); |
| 608 | bottom = bitmap.getHeight(); |
| 609 | } else { |
| 610 | left = src.left; |
| 611 | right = src.right; |
| 612 | top = src.top; |
| 613 | bottom = src.bottom; |
| 614 | } |
| 615 | |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 616 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, |
Romain Guy | 694b519 | 2010-07-21 21:33:20 -0700 | [diff] [blame] | 617 | dst.left, dst.top, dst.right, dst.bottom, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 618 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 619 | } |
| 620 | |
| 621 | @Override |
| 622 | public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 623 | // Shaders are ignored when drawing bitmaps |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 624 | int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 625 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 626 | nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, src.left, src.top, src.right, |
| 627 | src.bottom, dst.left, dst.top, dst.right, dst.bottom, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 628 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 629 | } |
| 630 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 631 | private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer, |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 632 | float srcLeft, float srcTop, float srcRight, float srcBottom, |
Romain Guy | dbd77cd | 2010-07-09 10:36:05 -0700 | [diff] [blame] | 633 | float left, float top, float right, float bottom, int paint); |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 634 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 635 | @Override |
| 636 | public void drawBitmap(int[] colors, int offset, int stride, float x, float y, |
| 637 | int width, int height, boolean hasAlpha, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 638 | // Shaders are ignored when drawing bitmaps |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 639 | int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 640 | final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; |
| 641 | final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config); |
| 642 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
Patrick Dubroy | e4ac2d6 | 2010-12-01 11:23:13 -0800 | [diff] [blame] | 643 | nDrawBitmap(mRenderer, b.mNativeBitmap, b.mBuffer, x, y, nativePaint); |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 644 | b.recycle(); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 645 | if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 646 | } |
| 647 | |
| 648 | @Override |
| 649 | public void drawBitmap(int[] colors, int offset, int stride, int x, int y, |
| 650 | int width, int height, boolean hasAlpha, Paint paint) { |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 651 | // Shaders are ignored when drawing bitmaps |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 652 | drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 653 | } |
| 654 | |
| 655 | @Override |
| 656 | public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, |
| 657 | int vertOffset, int[] colors, int colorOffset, Paint paint) { |
Romain Guy | 5a7b466 | 2011-01-20 19:09:30 -0800 | [diff] [blame] | 658 | if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) { |
| 659 | throw new ArrayIndexOutOfBoundsException(); |
| 660 | } |
| 661 | |
| 662 | if (meshWidth == 0 || meshHeight == 0) { |
| 663 | return; |
| 664 | } |
| 665 | |
| 666 | final int count = (meshWidth + 1) * (meshHeight + 1); |
| 667 | checkRange(verts.length, vertOffset, count * 2); |
| 668 | |
| 669 | // TODO: Colors are ignored for now |
| 670 | colors = null; |
| 671 | colorOffset = 0; |
| 672 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 673 | int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; |
Romain Guy | 5a7b466 | 2011-01-20 19:09:30 -0800 | [diff] [blame] | 674 | final int nativePaint = paint == null ? 0 : paint.mNativePaint; |
| 675 | nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight, |
| 676 | verts, vertOffset, colors, colorOffset, nativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 677 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 678 | } |
| 679 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 680 | private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer, |
Romain Guy | 5a7b466 | 2011-01-20 19:09:30 -0800 | [diff] [blame] | 681 | int meshWidth, int meshHeight, float[] verts, int vertOffset, |
| 682 | int[] colors, int colorOffset, int paint); |
| 683 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 684 | @Override |
| 685 | public void drawCircle(float cx, float cy, float radius, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 686 | int modifiers = setupModifiers(paint); |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 687 | nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 688 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 689 | } |
| 690 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 691 | private static native void nDrawCircle(int renderer, float cx, float cy, |
| 692 | float radius, int paint); |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 693 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 694 | @Override |
| 695 | public void drawColor(int color) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 696 | drawColor(color, PorterDuff.Mode.SRC_OVER); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 697 | } |
| 698 | |
| 699 | @Override |
| 700 | public void drawColor(int color, PorterDuff.Mode mode) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 701 | nDrawColor(mRenderer, color, mode.nativeInt); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 702 | } |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 703 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 704 | private static native void nDrawColor(int renderer, int color, int mode); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 705 | |
| 706 | @Override |
| 707 | public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 708 | mLine[0] = startX; |
| 709 | mLine[1] = startY; |
| 710 | mLine[2] = stopX; |
| 711 | mLine[3] = stopY; |
Romain Guy | 759ea80 | 2010-09-16 20:49:46 -0700 | [diff] [blame] | 712 | drawLines(mLine, 0, 4, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 713 | } |
| 714 | |
| 715 | @Override |
| 716 | public void drawLines(float[] pts, int offset, int count, Paint paint) { |
Romain Guy | 759ea80 | 2010-09-16 20:49:46 -0700 | [diff] [blame] | 717 | if ((offset | count) < 0 || offset + count > pts.length) { |
| 718 | throw new IllegalArgumentException("The lines array must contain 4 elements per line."); |
| 719 | } |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 720 | int modifiers = setupModifiers(paint); |
Romain Guy | 759ea80 | 2010-09-16 20:49:46 -0700 | [diff] [blame] | 721 | nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 722 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 723 | } |
| 724 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 725 | private static native void nDrawLines(int renderer, float[] points, |
| 726 | int offset, int count, int paint); |
Romain Guy | 759ea80 | 2010-09-16 20:49:46 -0700 | [diff] [blame] | 727 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 728 | @Override |
| 729 | public void drawLines(float[] pts, Paint paint) { |
Romain Guy | 759ea80 | 2010-09-16 20:49:46 -0700 | [diff] [blame] | 730 | drawLines(pts, 0, pts.length, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 731 | } |
| 732 | |
| 733 | @Override |
| 734 | public void drawOval(RectF oval, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 735 | int modifiers = setupModifiers(paint); |
Romain Guy | c1cd9ba3 | 2011-01-23 14:18:41 -0800 | [diff] [blame] | 736 | nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 737 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 738 | } |
| 739 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 740 | private static native void nDrawOval(int renderer, float left, float top, |
| 741 | float right, float bottom, int paint); |
Romain Guy | c1cd9ba3 | 2011-01-23 14:18:41 -0800 | [diff] [blame] | 742 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 743 | @Override |
| 744 | public void drawPaint(Paint paint) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 745 | final Rect r = mClipBounds; |
| 746 | nGetClipBounds(mRenderer, r); |
| 747 | drawRect(r.left, r.top, r.right, r.bottom, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 748 | } |
| 749 | |
| 750 | @Override |
| 751 | public void drawPath(Path path, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 752 | int modifiers = setupModifiers(paint); |
Romain Guy | a48a1a8 | 2010-08-10 14:59:15 -0700 | [diff] [blame] | 753 | if (path.isSimplePath) { |
| 754 | if (path.rects != null) { |
| 755 | nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint); |
| 756 | } |
| 757 | } else { |
| 758 | nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint); |
| 759 | } |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 760 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 761 | } |
| 762 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 763 | private static native void nDrawPath(int renderer, int path, int paint); |
| 764 | private static native void nDrawRects(int renderer, int region, int paint); |
Romain Guy | 7fbcc04 | 2010-08-04 15:40:07 -0700 | [diff] [blame] | 765 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 766 | @Override |
| 767 | public void drawPicture(Picture picture) { |
| 768 | throw new UnsupportedOperationException(); |
| 769 | } |
| 770 | |
| 771 | @Override |
| 772 | public void drawPicture(Picture picture, Rect dst) { |
| 773 | throw new UnsupportedOperationException(); |
| 774 | } |
| 775 | |
| 776 | @Override |
| 777 | public void drawPicture(Picture picture, RectF dst) { |
| 778 | throw new UnsupportedOperationException(); |
| 779 | } |
| 780 | |
| 781 | @Override |
| 782 | public void drawPoint(float x, float y, Paint paint) { |
Romain Guy | ce0537b | 2010-06-29 21:05:21 -0700 | [diff] [blame] | 783 | mPoint[0] = x; |
| 784 | mPoint[1] = y; |
Romain Guy | ed6fcb0 | 2011-03-21 13:11:28 -0700 | [diff] [blame] | 785 | drawPoints(mPoint, 0, 2, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 786 | } |
| 787 | |
| 788 | @Override |
| 789 | public void drawPoints(float[] pts, Paint paint) { |
Romain Guy | ed6fcb0 | 2011-03-21 13:11:28 -0700 | [diff] [blame] | 790 | drawPoints(pts, 0, pts.length, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 791 | } |
| 792 | |
| 793 | @Override |
Romain Guy | ed6fcb0 | 2011-03-21 13:11:28 -0700 | [diff] [blame] | 794 | public void drawPoints(float[] pts, int offset, int count, Paint paint) { |
| 795 | int modifiers = setupModifiers(paint); |
| 796 | nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint); |
| 797 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
| 798 | } |
| 799 | |
| 800 | private static native void nDrawPoints(int renderer, float[] points, |
| 801 | int offset, int count, int paint); |
| 802 | |
| 803 | @Override |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 804 | public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { |
Romain Guy | c1cd9ba3 | 2011-01-23 14:18:41 -0800 | [diff] [blame] | 805 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 806 | } |
| 807 | |
| 808 | @Override |
| 809 | public void drawPosText(String text, float[] pos, Paint paint) { |
Romain Guy | c1cd9ba3 | 2011-01-23 14:18:41 -0800 | [diff] [blame] | 810 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 811 | } |
| 812 | |
| 813 | @Override |
| 814 | public void drawRect(float left, float top, float right, float bottom, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 815 | int modifiers = setupModifiers(paint); |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 816 | nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 817 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 818 | } |
| 819 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 820 | private static native void nDrawRect(int renderer, float left, float top, |
| 821 | float right, float bottom, int paint); |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 822 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 823 | @Override |
| 824 | public void drawRect(Rect r, Paint paint) { |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 825 | drawRect(r.left, r.top, r.right, r.bottom, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 826 | } |
| 827 | |
| 828 | @Override |
Romain Guy | c7d5349 | 2010-06-25 13:41:57 -0700 | [diff] [blame] | 829 | public void drawRect(RectF r, Paint paint) { |
| 830 | drawRect(r.left, r.top, r.right, r.bottom, paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 831 | } |
| 832 | |
| 833 | @Override |
| 834 | public void drawRGB(int r, int g, int b) { |
Romain Guy | 85bf02f | 2010-06-22 13:11:24 -0700 | [diff] [blame] | 835 | drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 836 | } |
| 837 | |
| 838 | @Override |
| 839 | public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 840 | int modifiers = setupModifiers(paint); |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 841 | nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, |
| 842 | rx, ry, paint.mNativePaint); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 843 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 844 | } |
| 845 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 846 | private static native void nDrawRoundRect(int renderer, float left, float top, |
Romain Guy | 01d58e4 | 2011-01-19 21:54:02 -0800 | [diff] [blame] | 847 | float right, float bottom, float rx, float y, int paint); |
| 848 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 849 | @Override |
| 850 | public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 851 | if ((index | count | (index + count) | (text.length - index - count)) < 0) { |
| 852 | throw new IndexOutOfBoundsException(); |
| 853 | } |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 854 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 855 | int modifiers = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 856 | try { |
| 857 | nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint); |
| 858 | } finally { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 859 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 860 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 861 | } |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 862 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 863 | private static native void nDrawText(int renderer, char[] text, int index, int count, |
| 864 | float x, float y, int bidiFlags, int paint); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 865 | |
| 866 | @Override |
| 867 | public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 868 | int modifiers = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 869 | try { |
| 870 | if (text instanceof String || text instanceof SpannedString || |
| 871 | text instanceof SpannableString) { |
| 872 | nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, |
| 873 | paint.mNativePaint); |
| 874 | } else if (text instanceof GraphicsOperations) { |
| 875 | ((GraphicsOperations) text).drawText(this, start, end, x, y, |
| 876 | paint); |
| 877 | } else { |
| 878 | char[] buf = TemporaryBuffer.obtain(end - start); |
| 879 | TextUtils.getChars(text, start, end, buf, 0); |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 880 | nDrawText(mRenderer, buf, 0, end - start, x, y, |
| 881 | paint.mBidiFlags, paint.mNativePaint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 882 | TemporaryBuffer.recycle(buf); |
| 883 | } |
| 884 | } finally { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 885 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 886 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 887 | } |
| 888 | |
| 889 | @Override |
| 890 | public void drawText(String text, int start, int end, float x, float y, Paint paint) { |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 891 | if ((start | end | (end - start) | (text.length() - end)) < 0) { |
| 892 | throw new IndexOutOfBoundsException(); |
| 893 | } |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 894 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 895 | int modifiers = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 896 | try { |
| 897 | nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint); |
| 898 | } finally { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 899 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 900 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 901 | } |
| 902 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 903 | private static native void nDrawText(int renderer, String text, int start, int end, |
| 904 | float x, float y, int bidiFlags, int paint); |
Romain Guy | a1db574 | 2010-07-20 13:09:13 -0700 | [diff] [blame] | 905 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 906 | @Override |
| 907 | public void drawText(String text, float x, float y, Paint paint) { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 908 | int modifiers = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 909 | try { |
| 910 | nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, |
| 911 | paint.mNativePaint); |
| 912 | } finally { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 913 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 914 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 915 | } |
| 916 | |
| 917 | @Override |
| 918 | public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, |
| 919 | float vOffset, Paint paint) { |
Romain Guy | c1cd9ba3 | 2011-01-23 14:18:41 -0800 | [diff] [blame] | 920 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 921 | } |
| 922 | |
| 923 | @Override |
| 924 | public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { |
Romain Guy | c1cd9ba3 | 2011-01-23 14:18:41 -0800 | [diff] [blame] | 925 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 926 | } |
| 927 | |
| 928 | @Override |
| 929 | public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, |
| 930 | float x, float y, int dir, Paint paint) { |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 931 | if ((index | count | text.length - index - count) < 0) { |
| 932 | throw new IndexOutOfBoundsException(); |
| 933 | } |
| 934 | if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { |
| 935 | throw new IllegalArgumentException("Unknown direction: " + dir); |
| 936 | } |
| 937 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 938 | int modifiers = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 939 | try { |
| 940 | nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, |
| 941 | paint.mNativePaint); |
| 942 | } finally { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 943 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 944 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 945 | } |
| 946 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 947 | private static native void nDrawTextRun(int renderer, char[] text, int index, int count, |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 948 | int contextIndex, int contextCount, float x, float y, int dir, int nativePaint); |
| 949 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 950 | @Override |
| 951 | public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, |
| 952 | float x, float y, int dir, Paint paint) { |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 953 | if ((start | end | end - start | text.length() - end) < 0) { |
| 954 | throw new IndexOutOfBoundsException(); |
| 955 | } |
| 956 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 957 | int modifiers = setupModifiers(paint); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 958 | try { |
| 959 | int flags = dir == 0 ? 0 : 1; |
| 960 | if (text instanceof String || text instanceof SpannedString || |
| 961 | text instanceof SpannableString) { |
| 962 | nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, |
| 963 | contextEnd, x, y, flags, paint.mNativePaint); |
| 964 | } else if (text instanceof GraphicsOperations) { |
| 965 | ((GraphicsOperations) text).drawTextRun(this, start, end, |
| 966 | contextStart, contextEnd, x, y, flags, paint); |
| 967 | } else { |
| 968 | int contextLen = contextEnd - contextStart; |
| 969 | int len = end - start; |
| 970 | char[] buf = TemporaryBuffer.obtain(contextLen); |
| 971 | TextUtils.getChars(text, contextStart, contextEnd, buf, 0); |
| 972 | nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, |
| 973 | x, y, flags, paint.mNativePaint); |
| 974 | TemporaryBuffer.recycle(buf); |
| 975 | } |
| 976 | } finally { |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 977 | if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 978 | } |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 979 | } |
| 980 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 981 | private static native void nDrawTextRun(int renderer, String text, int start, int end, |
Romain Guy | 61c8c9c | 2010-08-09 20:48:09 -0700 | [diff] [blame] | 982 | int contextStart, int contextEnd, float x, float y, int flags, int nativePaint); |
| 983 | |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 984 | @Override |
| 985 | public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, |
| 986 | float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, |
| 987 | int indexOffset, int indexCount, Paint paint) { |
Romain Guy | 6926c72 | 2010-07-12 20:20:03 -0700 | [diff] [blame] | 988 | // TODO: Implement |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 989 | } |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 990 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 991 | private int setupModifiers(Bitmap b, Paint paint) { |
| 992 | if (b.getConfig() == Bitmap.Config.ALPHA_8) { |
| 993 | return setupModifiers(paint); |
| 994 | } |
Romain Guy | 5621527 | 2011-03-23 16:55:38 -0700 | [diff] [blame] | 995 | |
| 996 | final ColorFilter filter = paint.getColorFilter(); |
| 997 | if (filter != null) { |
| 998 | nSetupColorFilter(mRenderer, filter.nativeColorFilter); |
| 999 | return MODIFIER_COLOR_FILTER; |
| 1000 | } |
| 1001 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1002 | return MODIFIER_NONE; |
| 1003 | } |
| 1004 | |
| 1005 | private int setupModifiers(Paint paint) { |
| 1006 | int modifiers = MODIFIER_NONE; |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 1007 | |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 1008 | if (paint.hasShadow) { |
| 1009 | nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy, |
| 1010 | paint.shadowColor); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1011 | modifiers |= MODIFIER_SHADOW; |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 1012 | } |
| 1013 | |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 1014 | final Shader shader = paint.getShader(); |
| 1015 | if (shader != null) { |
Romain Guy | 06f96e2 | 2010-07-30 19:18:16 -0700 | [diff] [blame] | 1016 | nSetupShader(mRenderer, shader.native_shader); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1017 | modifiers |= MODIFIER_SHADER; |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 1018 | } |
| 1019 | |
| 1020 | final ColorFilter filter = paint.getColorFilter(); |
| 1021 | if (filter != null) { |
| 1022 | nSetupColorFilter(mRenderer, filter.nativeColorFilter); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1023 | modifiers |= MODIFIER_COLOR_FILTER; |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 1024 | } |
| 1025 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1026 | return modifiers; |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 1027 | } |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 1028 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1029 | private int setupColorFilter(Paint paint) { |
Romain Guy | db1938e | 2010-08-02 18:50:22 -0700 | [diff] [blame] | 1030 | final ColorFilter filter = paint.getColorFilter(); |
| 1031 | if (filter != null) { |
| 1032 | nSetupColorFilter(mRenderer, filter.nativeColorFilter); |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1033 | return MODIFIER_COLOR_FILTER; |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 1034 | } |
Romain Guy | 5621527 | 2011-03-23 16:55:38 -0700 | [diff] [blame] | 1035 | return MODIFIER_NONE; |
Romain Guy | d27977d | 2010-07-14 19:18:51 -0700 | [diff] [blame] | 1036 | } |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1037 | |
Romain Guy | 7d7b549 | 2011-01-24 16:33:45 -0800 | [diff] [blame] | 1038 | private static native void nSetupShader(int renderer, int shader); |
| 1039 | private static native void nSetupColorFilter(int renderer, int colorFilter); |
| 1040 | private static native void nSetupShadow(int renderer, float radius, |
| 1041 | float dx, float dy, int color); |
Romain Guy | 1e45aae | 2010-08-13 19:39:53 -0700 | [diff] [blame] | 1042 | |
Romain Guy | a168d73 | 2011-03-18 16:50:13 -0700 | [diff] [blame] | 1043 | private static native void nResetModifiers(int renderer, int modifiers); |
Romain Guy | e4d0112 | 2010-06-16 18:44:05 -0700 | [diff] [blame] | 1044 | } |