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