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