1 /* 2 * Copyright (C) 2014 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 #include "Picture.h" 18 #include "SkStream.h" 19 20 #include <memory> 21 #include <hwui/Canvas.h> 22 23 namespace android { 24 25 Picture::Picture(const Picture* src) { 26 if (NULL != src) { 27 mWidth = src->width(); 28 mHeight = src->height(); 29 if (NULL != src->mPicture.get()) { 30 mPicture.reset(SkRef(src->mPicture.get())); 31 } else if (NULL != src->mRecorder.get()) { 32 mPicture.reset(src->makePartialCopy()); 33 } 34 validate(); 35 } else { 36 mWidth = 0; 37 mHeight = 0; 38 } 39 } 40 41 Canvas* Picture::beginRecording(int width, int height) { 42 mPicture.reset(NULL); 43 mRecorder.reset(new SkPictureRecorder); 44 mWidth = width; 45 mHeight = height; 46 SkCanvas* canvas = mRecorder->beginRecording(width, height, NULL, 0); 47 return Canvas::create_canvas(canvas); 48 } 49 50 void Picture::endRecording() { 51 if (NULL != mRecorder.get()) { 52 mPicture.reset(mRecorder->endRecording()); 53 validate(); 54 mRecorder.reset(NULL); 55 } 56 } 57 58 int Picture::width() const { 59 validate(); 60 return mWidth; 61 } 62 63 int Picture::height() const { 64 validate(); 65 return mHeight; 66 } 67 68 Picture* Picture::CreateFromStream(SkStream* stream) { 69 Picture* newPict = new Picture; 70 71 SkPicture* skPicture = SkPicture::CreateFromStream(stream); 72 if (NULL != skPicture) { 73 newPict->mPicture.reset(skPicture); 74 75 const SkIRect cullRect = skPicture->cullRect().roundOut(); 76 newPict->mWidth = cullRect.width(); 77 newPict->mHeight = cullRect.height(); 78 } 79 80 return newPict; 81 } 82 83 void Picture::serialize(SkWStream* stream) const { 84 if (NULL != mRecorder.get()) { 85 std::unique_ptr<SkPicture> tempPict(this->makePartialCopy()); 86 tempPict->serialize(stream); 87 } else if (NULL != mPicture.get()) { 88 validate(); 89 mPicture->serialize(stream); 90 } else { 91 SkPictureRecorder recorder; 92 recorder.beginRecording(0, 0); 93 std::unique_ptr<SkPicture> empty(recorder.endRecording()); 94 empty->serialize(stream); 95 } 96 } 97 98 void Picture::draw(Canvas* canvas) { 99 if (NULL != mRecorder.get()) { 100 this->endRecording(); 101 SkASSERT(NULL != mPicture.get()); 102 } 103 validate(); 104 if (NULL != mPicture.get()) { 105 mPicture.get()->playback(canvas->asSkCanvas()); 106 } 107 } 108 109 SkPicture* Picture::makePartialCopy() const { 110 SkASSERT(NULL != mRecorder.get()); 111 112 SkPictureRecorder reRecorder; 113 114 SkCanvas* canvas = reRecorder.beginRecording(mWidth, mHeight, NULL, 0); 115 mRecorder->partialReplay(canvas); 116 return reRecorder.endRecording(); 117 } 118 119 void Picture::validate() const { 120 #ifdef SK_DEBUG 121 if (NULL != mPicture.get()) { 122 SkRect cullRect = mPicture->cullRect(); 123 SkRect myRect = SkRect::MakeWH(SkIntToScalar(mWidth), SkIntToScalar(mHeight)); 124 SkASSERT(cullRect == myRect); 125 } 126 #endif 127 } 128 129 }; // namespace android 130