SamplePicture.cpp revision 5b132b28da61e89cdcb84e95f30a58f8184739fc
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SampleCode.h" 9#include "SkDumpCanvas.h" 10#include "SkView.h" 11#include "SkCanvas.h" 12#include "Sk64.h" 13#include "SkGradientShader.h" 14#include "SkGraphics.h" 15#include "SkImageDecoder.h" 16#include "SkPath.h" 17#include "SkPicture.h" 18#include "SkRandom.h" 19#include "SkRegion.h" 20#include "SkShader.h" 21#include "SkUtils.h" 22#include "SkColorPriv.h" 23#include "SkColorFilter.h" 24#include "SkTime.h" 25#include "SkTypeface.h" 26#include "SkXfermode.h" 27 28#include "SkStream.h" 29#include "SkXMLParser.h" 30 31/////////////////////////////////////////////////////////////////////////////// 32 33#include "SkImageRef_GlobalPool.h" 34 35static SkBitmap load_bitmap() { 36 SkBitmap bm; 37 SkStreamAsset* stream = SkStream::NewFromFile("/skimages/sesame_street_ensemble-hp.jpg"); 38 if (stream) { 39 SkAutoUnref aur(stream); 40 41 if (SkImageDecoder::DecodeStream(stream, &bm, SkBitmap::kNo_Config, 42 SkImageDecoder::kDecodeBounds_Mode)) { 43 SkPixelRef* pr = new SkImageRef_GlobalPool(stream, bm.config(), 1); 44 bm.setPixelRef(pr)->unref(); 45 } 46 } 47 return bm; 48} 49 50static void drawCircle(SkCanvas* canvas, int r, SkColor color) { 51 SkPaint paint; 52 paint.setAntiAlias(true); 53 paint.setColor(color); 54 55 canvas->drawCircle(SkIntToScalar(r), SkIntToScalar(r), SkIntToScalar(r), 56 paint); 57} 58 59class PictureView : public SampleView { 60 SkBitmap fBitmap; 61public: 62 PictureView() { 63 SkImageRef_GlobalPool::SetRAMBudget(16 * 1024); 64 65 fBitmap = load_bitmap(); 66 67 fPicture = new SkPicture; 68 SkCanvas* canvas = fPicture->beginRecording(100, 100); 69 SkPaint paint; 70 paint.setAntiAlias(true); 71 72 canvas->drawBitmap(fBitmap, 0, 0, NULL); 73 74 drawCircle(canvas, 50, SK_ColorBLACK); 75 fSubPicture = new SkPicture; 76 canvas->drawPicture(*fSubPicture); 77 canvas->translate(SkIntToScalar(50), 0); 78 canvas->drawPicture(*fSubPicture); 79 canvas->translate(0, SkIntToScalar(50)); 80 canvas->drawPicture(*fSubPicture); 81 canvas->translate(SkIntToScalar(-50), 0); 82 canvas->drawPicture(*fSubPicture); 83 // fPicture now has (4) references to us. We can release ours, and just 84 // unref fPicture in our destructor, and it will in turn take care of 85 // the other references to fSubPicture 86 fSubPicture->unref(); 87 } 88 89 virtual ~PictureView() { 90 fPicture->unref(); 91 } 92 93protected: 94 // overrides from SkEventSink 95 virtual bool onQuery(SkEvent* evt) { 96 if (SampleCode::TitleQ(*evt)) { 97 SampleCode::TitleR(evt, "Picture"); 98 return true; 99 } 100 return this->INHERITED::onQuery(evt); 101 } 102 103 void drawSomething(SkCanvas* canvas) { 104 SkPaint paint; 105 106 canvas->save(); 107 canvas->scale(0.5f, 0.5f); 108 canvas->drawBitmap(fBitmap, 0, 0, NULL); 109 canvas->restore(); 110 111 const char beforeStr[] = "before circle"; 112 const char afterStr[] = "after circle"; 113 114 paint.setAntiAlias(true); 115 116 paint.setColor(SK_ColorRED); 117 canvas->drawData(beforeStr, sizeof(beforeStr)); 118 canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50), 119 SkIntToScalar(40), paint); 120 canvas->drawData(afterStr, sizeof(afterStr)); 121 paint.setColor(SK_ColorBLACK); 122 paint.setTextSize(SkIntToScalar(40)); 123 canvas->drawText("Picture", 7, SkIntToScalar(50), SkIntToScalar(62), 124 paint); 125 126 } 127 128 virtual void onDrawContent(SkCanvas* canvas) { 129 drawSomething(canvas); 130 131 SkPicture* pict = new SkPicture; 132 SkAutoUnref aur(pict); 133 134 drawSomething(pict->beginRecording(100, 100)); 135 pict->endRecording(); 136 137 canvas->save(); 138 canvas->translate(SkIntToScalar(300), SkIntToScalar(50)); 139 canvas->scale(-SK_Scalar1, -SK_Scalar1); 140 canvas->translate(-SkIntToScalar(100), -SkIntToScalar(50)); 141 canvas->drawPicture(*pict); 142 canvas->restore(); 143 144 canvas->save(); 145 canvas->translate(SkIntToScalar(200), SkIntToScalar(150)); 146 canvas->scale(SK_Scalar1, -SK_Scalar1); 147 canvas->translate(0, -SkIntToScalar(50)); 148 canvas->drawPicture(*pict); 149 canvas->restore(); 150 151 canvas->save(); 152 canvas->translate(SkIntToScalar(100), SkIntToScalar(100)); 153 canvas->scale(-SK_Scalar1, SK_Scalar1); 154 canvas->translate(-SkIntToScalar(100), 0); 155 canvas->drawPicture(*pict); 156 canvas->restore(); 157 158#ifdef SK_DEVELOPER 159 if (false) { 160 SkDebugfDumper dumper; 161 SkDumpCanvas dumpCanvas(&dumper); 162 dumpCanvas.drawPicture(*pict); 163 } 164#endif 165 166 // test that we can re-record a subpicture, and see the results 167 168 SkRandom rand(SampleCode::GetAnimTime()); 169 canvas->translate(SkIntToScalar(10), SkIntToScalar(250)); 170 drawCircle(fSubPicture->beginRecording(50, 50), 25, 171 rand.nextU() | 0xFF000000); 172 canvas->drawPicture(*fPicture); 173 delayInval(500); 174 } 175 176private: 177 #define INVAL_ALL_TYPE "inval-all" 178 179 void delayInval(SkMSec delay) { 180 (new SkEvent(INVAL_ALL_TYPE, this->getSinkID()))->postDelay(delay); 181 } 182 183 virtual bool onEvent(const SkEvent& evt) { 184 if (evt.isType(INVAL_ALL_TYPE)) { 185 this->inval(NULL); 186 return true; 187 } 188 return this->INHERITED::onEvent(evt); 189 } 190 191 SkPicture* fPicture; 192 SkPicture* fSubPicture; 193 194 typedef SampleView INHERITED; 195}; 196 197////////////////////////////////////////////////////////////////////////////// 198 199static SkView* MyFactory() { return new PictureView; } 200static SkViewRegister reg(MyFactory); 201