19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
23cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger * A Picture records drawing calls (via the canvas returned by beginRecording)
24cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger * and can then play them back into Canvas (via {@link Picture#draw(Canvas)} or
25cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger * {@link Canvas#drawPicture(Picture)}).For most content (e.g. text, lines, rectangles),
26cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger * drawing a sequence from a picture can be faster than the equivalent API
27cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger * calls, since the picture performs its playback without incurring any
28cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger * method-call overhead.
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Picture {
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Canvas mRecordingCanvas;
3236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private final long mNativePicture;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int WORKING_STREAM_STORAGE = 16 * 1024;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger    /**
37cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * Creates an empty picture that is ready to record.
38cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     */
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Picture() {
404b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        this(nativeConstructor(0));
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a picture by making a copy of what has already been recorded in
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * src. The contents of src are unchanged, and if src changes later, those
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * changes will not be reflected in this picture.
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Picture(Picture src) {
494b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        this(nativeConstructor(src != null ? src.mNativePicture : 0));
504b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
514b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger
524b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    private Picture(long nativePicture) {
534b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        if (nativePicture == 0) {
544b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger            throw new RuntimeException();
554b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        }
564b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mNativePicture = nativePicture;
574b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
584b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger
594b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    @Override
604b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    protected void finalize() throws Throwable {
614b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        try {
624b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger            nativeDestructor(mNativePicture);
634b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        } finally {
644b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger            super.finalize();
654b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
67dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * To record a picture, call beginRecording() and then draw into the Canvas
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that is returned. Nothing we appear on screen, but all of the draw
71cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * commands (e.g. {@link Canvas#drawRect(Rect, Paint)}) will be recorded.
72cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * To stop recording, call endRecording(). After endRecording() the Canvas
73cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * that was returned must no longer be used, and nothing should be drawn
74cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * into it.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Canvas beginRecording(int width, int height) {
7736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long ni = nativeBeginRecording(mNativePicture, width, height);
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRecordingCanvas = new RecordingCanvas(this, ni);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mRecordingCanvas;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
81dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call endRecording when the picture is built. After this call, the picture
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may be drawn, but the canvas that was returned by beginRecording must not
85cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * be used anymore. This is automatically called if {@link Picture#draw}
86cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * or {@link Canvas#drawPicture(Picture)} is called.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void endRecording() {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRecordingCanvas != null) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRecordingCanvas = null;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nativeEndRecording(mNativePicture);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Get the width of the picture as passed to beginRecording. This
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does not reflect (per se) the content of the picture.
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
994b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    public int getWidth() {
1004b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger      return nativeGetWidth(mNativePicture);
1014b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Get the height of the picture as passed to beginRecording. This
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does not reflect (per se) the content of the picture.
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1074b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    public int getHeight() {
1084b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger      return nativeGetHeight(mNativePicture);
1094b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
110dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
112dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     * Draw this picture on the canvas.
113dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     * <p>
114955d8d69ea6caabce1461dc25b339b9bf9dc61a6Dianne Hackborn     * Prior to {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this call could
115dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     * have the side effect of changing the matrix and clip of the canvas
116dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     * if this picture had imbalanced saves/restores.
117dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     *
118cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * <p>
119cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * <strong>Note:</strong> This forces the picture to internally call
120cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * {@link Picture#endRecording()} in order to prepare for playback.
121cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     *
122dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     * @param canvas  The picture is drawn to this canvas
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
12596890564bdbd2f2a41dfc323fc8b3938fb335639Chris Craik        if (canvas.isHardwareAccelerated()) {
12696890564bdbd2f2a41dfc323fc8b3938fb335639Chris Craik            throw new IllegalArgumentException(
12796890564bdbd2f2a41dfc323fc8b3938fb335639Chris Craik                    "Picture playback is only supported on software canvas.");
12896890564bdbd2f2a41dfc323fc8b3938fb335639Chris Craik        }
12996890564bdbd2f2a41dfc323fc8b3938fb335639Chris Craik
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRecordingCanvas != null) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            endRecording();
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1335c3d927e17e98e8fd4a9f3c86f7f4def0bcfa816Florin Malita        nativeDraw(canvas.getNativeCanvasWrapper(), mNativePicture);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new picture (already recorded) from the data in the stream. This
138cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * data was generated by a previous call to writeToStream(). Pictures that
139cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * have been persisted across device restarts are not guaranteed to decode
140cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * properly and are highly discouraged.
141cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     *
142cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * <p>
143f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * <strong>Note:</strong> a picture created from an input stream cannot be
144f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * replayed on a hardware accelerated canvas.
145dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips     *
146cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * @see #writeToStream(java.io.OutputStream)
147cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * @deprecated The recommended alternative is to not use writeToStream and
148cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * instead draw the picture into a Bitmap from which you can persist it as
149cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * raw or compressed pixels.
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
151cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger    @Deprecated
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Picture createFromStream(InputStream stream) {
1534b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        return new Picture(nativeCreateFromStream(stream, new byte[WORKING_STREAM_STORAGE]));
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Write the picture contents to a stream. The data can be used to recreate
158cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * the picture in this or another process by calling createFromStream(...)
159cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * The resulting stream is NOT to be persisted across device restarts as
160cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * there is no guarantee that the Picture can be successfully reconstructed.
161f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     *
162cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * <p>
163f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * <strong>Note:</strong> a picture created from an input stream cannot be
164f9d9c065ed75f1196316a9a31f92309f602cef76Romain Guy     * replayed on a hardware accelerated canvas.
165cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     *
166cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * @see #createFromStream(java.io.InputStream)
167cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * @deprecated The recommended alternative is to draw the picture into a
168cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger     * Bitmap from which you can persist it as raw or compressed pixels.
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
170cdac497289fd2c39a352f6167dae3f77cc608cb8Derek Sollenberger    @Deprecated
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToStream(OutputStream stream) {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // do explicit check before calling the native method
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (stream == null) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException();
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!nativeWriteToStream(mNativePicture, stream,
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                             new byte[WORKING_STREAM_STORAGE])) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException();
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // return empty picture if src is 0, or a copy of the native src
18336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeConstructor(long nativeSrcOr0);
1844b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    private static native long nativeCreateFromStream(InputStream stream, byte[] storage);
1854b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    private static native int nativeGetWidth(long nativePicture);
1864b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    private static native int nativeGetHeight(long nativePicture);
1874b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    private static native long nativeBeginRecording(long nativeCanvas, int w, int h);
18836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeEndRecording(long nativeCanvas);
18936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeDraw(long nativeCanvas, long nativePicture);
19036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeWriteToStream(long nativePicture,
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                           OutputStream stream, byte[] storage);
19236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeDestructor(long nativePicture);
193dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class RecordingCanvas extends Canvas {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Picture mPicture;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        public RecordingCanvas(Picture pict, long nativeCanvas) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(nativeCanvas);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPicture = pict;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
201dcc64a4e6b96d15b8b966dcb62f29a370e562271Robert Phillips
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setBitmap(Bitmap bitmap) {
2044b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger            throw new RuntimeException("Cannot call setBitmap on a picture canvas");
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void drawPicture(Picture picture) {
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mPicture == picture) {
2104b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger                throw new RuntimeException("Cannot draw a picture into its recording canvas");
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.drawPicture(picture);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
216