19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
24b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger * Copyright (C) 2014 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
178872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger#include "Canvas.h"
184b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger#include "Picture.h"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20ca32021b43f326af7d3f4ae041f8db297f98a518Leon Scroggins III#include "SkStream.h"
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22a0dc40409265fa46c3ceee91ec68d2f45b8f67e8Derek Sollenbergernamespace android {
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
244b0959d8db20c08ab1fed37f397b303af229162bDerek SollenbergerPicture::Picture(const Picture* src) {
254b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != src) {
264b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mWidth = src->width();
274b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mHeight = src->height();
284b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        if (NULL != src->mPicture.get()) {
294b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger            mPicture.reset(SkRef(src->mPicture.get()));
304b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        } if (NULL != src->mRecorder.get()) {
314b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger            mPicture.reset(src->makePartialCopy());
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
334b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    } else {
344b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mWidth = 0;
354b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mHeight = 0;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
374b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
3836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
398872b38ef403cc2c44aca07d392f5e9426fd7f54Derek SollenbergerCanvas* Picture::beginRecording(int width, int height) {
404b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    mPicture.reset(NULL);
414b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    mRecorder.reset(new SkPictureRecorder);
424b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    mWidth = width;
434b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    mHeight = height;
448872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    SkCanvas* canvas = mRecorder->beginRecording(width, height, NULL, 0);
45febccd05f2e9ad2422d74fcf33ec9bc900ae83bbRaph Levien    // the java side will wrap this guy in a Canvas.java, which will call
46febccd05f2e9ad2422d74fcf33ec9bc900ae83bbRaph Levien    // unref in its finalizer, so we have to ref it here, so that both that
47febccd05f2e9ad2422d74fcf33ec9bc900ae83bbRaph Levien    // Canvas.java and our picture can both be owners
48febccd05f2e9ad2422d74fcf33ec9bc900ae83bbRaph Levien    canvas->ref();
498872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger    return Canvas::create_canvas(canvas);
504b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
5136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
524b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenbergervoid Picture::endRecording() {
534b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != mRecorder.get()) {
544b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mPicture.reset(mRecorder->endRecording());
554b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mRecorder.reset(NULL);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
574b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
5836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
594b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenbergerint Picture::width() const {
604b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != mPicture.get()) {
614b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkASSERT(mPicture->width() == mWidth);
624b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkASSERT(mPicture->height() == mHeight);
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
654b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    return mWidth;
664b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
6736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
684b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenbergerint Picture::height() const {
694b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != mPicture.get()) {
704b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkASSERT(mPicture->width() == mWidth);
714b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkASSERT(mPicture->height() == mHeight);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
744b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    return mHeight;
754b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
7636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
774b0959d8db20c08ab1fed37f397b303af229162bDerek SollenbergerPicture* Picture::CreateFromStream(SkStream* stream) {
784b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    Picture* newPict = new Picture;
7936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
804b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    newPict->mPicture.reset(SkPicture::CreateFromStream(stream));
814b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != newPict->mPicture.get()) {
824b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        newPict->mWidth = newPict->mPicture->width();
834b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        newPict->mHeight = newPict->mPicture->height();
844b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
8536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
864b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    return newPict;
874b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
8836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
894b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenbergervoid Picture::serialize(SkWStream* stream) const {
904b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != mRecorder.get()) {
914b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkAutoTDelete<SkPicture> tempPict(this->makePartialCopy());
924b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        tempPict->serialize(stream);
934b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    } else if (NULL != mPicture.get()) {
944b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        mPicture->serialize(stream);
954b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    } else {
964b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkPicture empty;
974b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        empty.serialize(stream);
984b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
1018872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenbergervoid Picture::draw(Canvas* canvas) {
1024b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != mRecorder.get()) {
1034b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        this->endRecording();
1044b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        SkASSERT(NULL != mPicture.get());
1054b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
1064b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    if (NULL != mPicture.get()) {
1074b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger        // TODO: remove this const_cast once pictures are immutable
1088872b38ef403cc2c44aca07d392f5e9426fd7f54Derek Sollenberger        const_cast<SkPicture*>(mPicture.get())->draw(canvas->getSkCanvas());
1094b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1124b0959d8db20c08ab1fed37f397b303af229162bDerek SollenbergerSkPicture* Picture::makePartialCopy() const {
1134b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    SkASSERT(NULL != mRecorder.get());
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1154b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    SkPictureRecorder reRecorder;
1164b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger
1174b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight, NULL, 0);
1184b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    mRecorder->partialReplay(canvas);
1194b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger    return reRecorder.endRecording();
1204b0959d8db20c08ab1fed37f397b303af229162bDerek Sollenberger}
121a0dc40409265fa46c3ceee91ec68d2f45b8f67e8Derek Sollenberger
122a0dc40409265fa46c3ceee91ec68d2f45b8f67e8Derek Sollenberger}; // namespace android
123