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