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