1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include <memory> 9 10 #include "Model.h" 11 12 #include "SkBitmap.h" 13 #include "SkCanvas.h" 14 #include "SkDebugCanvas.h" 15 #include "SkPicture.h" 16 #include "SkStream.h" 17 Model()18Model::Model() : fCurOp(0) { 19 SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024); 20 fBM.allocPixels(ii, 0); 21 } 22 ~Model()23Model::~Model() { 24 this->resetOpList(); 25 } 26 load(const char * filename)27Model::ErrorCode Model::load(const char* filename) { 28 std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(filename); 29 if (!stream) { 30 return ErrorCode::kCouldntOpenFile; 31 } 32 sk_sp<SkPicture> pic(SkPicture::MakeFromStream(stream.get())); 33 if (!pic) { 34 return ErrorCode::kCouldntDecodeSKP; 35 } 36 37 { 38 std::unique_ptr<SkDebugCanvas> temp(new SkDebugCanvas( 39 SkScalarCeilToInt(pic->cullRect().width()), 40 SkScalarCeilToInt(pic->cullRect().height()))); 41 42 temp->setPicture(pic.get()); 43 pic->playback(temp.get()); 44 temp->setPicture(nullptr); 45 this->resetOpList(); 46 temp->detachCommands(&fOps); 47 } 48 49 this->setCurOp(fOps.count()-1); 50 51 return ErrorCode::kOK; 52 } 53 ErrorString(ErrorCode err)54const char* Model::ErrorString(ErrorCode err) { 55 static const char* kStrings[] = { 56 "OK", 57 "Couldn't read file", 58 "Couldn't decode picture" 59 }; 60 61 return kStrings[(int)err]; 62 } 63 getOpName(int index) const64const char* Model::getOpName(int index) const { 65 return SkDrawCommand::GetCommandString(fOps[index]->getType()); 66 } 67 isHierarchyPush(int index) const68bool Model::isHierarchyPush(int index) const { 69 SkDrawCommand::OpType type = fOps[index]->getType(); 70 71 return SkDrawCommand::kSave_OpType == type || 72 SkDrawCommand::kSaveLayer_OpType == type || 73 SkDrawCommand::kBeginDrawPicture_OpType == type; 74 } 75 isHierarchyPop(int index) const76bool Model::isHierarchyPop(int index) const { 77 SkDrawCommand::OpType type = fOps[index]->getType(); 78 79 return SkDrawCommand::kRestore_OpType == type || 80 SkDrawCommand::kEndDrawPicture_OpType == type; 81 } 82 setCurOp(int curOp)83void Model::setCurOp(int curOp) { 84 SkASSERT(curOp < fOps.count()); 85 86 if (curOp == fCurOp) { 87 return; // the render state is already up to date 88 } 89 90 fCurOp = curOp; 91 this->drawTo(fCurOp); 92 } 93 drawTo(int index)94void Model::drawTo(int index) { 95 SkASSERT(index < fOps.count()); 96 97 SkCanvas canvas(fBM); 98 99 int saveCount = canvas.save(); 100 101 for (int i = 0; i <= index; ++i) { 102 if (fOps[i]->isVisible()) { 103 fOps[i]->execute(&canvas); 104 } 105 } 106 107 canvas.restoreToCount(saveCount); 108 } 109 resetOpList()110void Model::resetOpList() { 111 for (int i = 0; i < fOps.count(); ++i) { 112 delete fOps[i]; 113 } 114 fOps.reset(); 115 fCurOp = 0; 116 } 117