Home | History | Annotate | Download | only in samplecode
      1 /*
      2  * Copyright 2011 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 "gm.h"
      9 
     10 #include "Resources.h"
     11 #include "SampleCode.h"
     12 #include "SkCanvas.h"
     13 #include "SkColorFilter.h"
     14 #include "SkColorPriv.h"
     15 #include "SkData.h"
     16 #include "SkDecodingImageGenerator.h"
     17 #include "SkDumpCanvas.h"
     18 #include "SkGradientShader.h"
     19 #include "SkGraphics.h"
     20 #include "SkImageDecoder.h"
     21 #include "SkOSFile.h"
     22 #include "SkPath.h"
     23 #include "SkPicture.h"
     24 #include "SkPictureRecorder.h"
     25 #include "SkRandom.h"
     26 #include "SkRegion.h"
     27 #include "SkShader.h"
     28 #include "SkStream.h"
     29 #include "SkTime.h"
     30 #include "SkTypeface.h"
     31 #include "SkUtils.h"
     32 #include "SkView.h"
     33 #include "SkXMLParser.h"
     34 #include "SkXfermode.h"
     35 
     36 ///////////////////////////////////////////////////////////////////////////////
     37 
     38 static SkBitmap load_bitmap() {
     39     SkBitmap bm;
     40     SkString resourcePath = GetResourcePath();
     41     SkString path = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_512.png");
     42     SkAutoDataUnref data(SkData::NewFromFileName(path.c_str()));
     43     if (data.get() != NULL) {
     44         SkInstallDiscardablePixelRef(SkDecodingImageGenerator::Create(
     45             data, SkDecodingImageGenerator::Options()), &bm);
     46     }
     47     return bm;
     48 }
     49 
     50 static 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 
     59 class PictureView : public SampleView {
     60     SkBitmap fBitmap;
     61 public:
     62     PictureView() {
     63 
     64         fBitmap = load_bitmap();
     65 
     66         SkPictureRecorder recorder;
     67 
     68         recorder.beginRecording(100, 100, NULL, 0);
     69         fSubPicture = recorder.endRecording();
     70 
     71         SkCanvas* canvas = recorder.beginRecording(100, 100, NULL, 0);
     72         SkPaint paint;
     73         paint.setAntiAlias(true);
     74 
     75         canvas->drawBitmap(fBitmap, 0, 0, NULL);
     76 
     77         drawCircle(canvas, 50, SK_ColorBLACK);
     78         canvas->drawPicture(fSubPicture);
     79         canvas->translate(SkIntToScalar(50), 0);
     80         canvas->drawPicture(fSubPicture);
     81         canvas->translate(0, SkIntToScalar(50));
     82         canvas->drawPicture(fSubPicture);
     83         canvas->translate(SkIntToScalar(-50), 0);
     84         canvas->drawPicture(fSubPicture);
     85 
     86         fPicture = recorder.endRecording();
     87 
     88         // fPicture now has (4) references to fSubPicture. We can release our ref,
     89         // and just unref fPicture in our destructor, and it will in turn take care of
     90         // the other references to fSubPicture
     91         fSubPicture->unref();
     92     }
     93 
     94     virtual ~PictureView() {
     95         fPicture->unref();
     96     }
     97 
     98 protected:
     99     // overrides from SkEventSink
    100     virtual bool onQuery(SkEvent* evt) {
    101         if (SampleCode::TitleQ(*evt)) {
    102             SampleCode::TitleR(evt, "Picture");
    103             return true;
    104         }
    105         return this->INHERITED::onQuery(evt);
    106     }
    107 
    108     void drawSomething(SkCanvas* canvas) {
    109         SkPaint paint;
    110 
    111         canvas->save();
    112         canvas->scale(0.5f, 0.5f);
    113         canvas->drawBitmap(fBitmap, 0, 0, NULL);
    114         canvas->restore();
    115 
    116         const char beforeStr[] = "before circle";
    117         const char afterStr[] = "after circle";
    118 
    119         paint.setAntiAlias(true);
    120 
    121         paint.setColor(SK_ColorRED);
    122         canvas->drawData(beforeStr, sizeof(beforeStr));
    123         canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
    124                            SkIntToScalar(40), paint);
    125         canvas->drawData(afterStr, sizeof(afterStr));
    126         paint.setColor(SK_ColorBLACK);
    127         paint.setTextSize(SkIntToScalar(40));
    128         canvas->drawText("Picture", 7, SkIntToScalar(50), SkIntToScalar(62),
    129                          paint);
    130 
    131     }
    132 
    133     virtual void onDrawContent(SkCanvas* canvas) {
    134         this->drawSomething(canvas);
    135 
    136         SkPictureRecorder recorder;
    137         this->drawSomething(recorder.beginRecording(100, 100, NULL, 0));
    138         SkAutoTUnref<SkPicture> pict(recorder.endRecording());
    139 
    140         canvas->save();
    141         canvas->translate(SkIntToScalar(300), SkIntToScalar(50));
    142         canvas->scale(-SK_Scalar1, -SK_Scalar1);
    143         canvas->translate(-SkIntToScalar(100), -SkIntToScalar(50));
    144         canvas->drawPicture(pict);
    145         canvas->restore();
    146 
    147         canvas->save();
    148         canvas->translate(SkIntToScalar(200), SkIntToScalar(150));
    149         canvas->scale(SK_Scalar1, -SK_Scalar1);
    150         canvas->translate(0, -SkIntToScalar(50));
    151         canvas->drawPicture(pict);
    152         canvas->restore();
    153 
    154         canvas->save();
    155         canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
    156         canvas->scale(-SK_Scalar1, SK_Scalar1);
    157         canvas->translate(-SkIntToScalar(100), 0);
    158         canvas->drawPicture(pict);
    159         canvas->restore();
    160 
    161 #ifdef SK_DEVELOPER
    162         if (false) {
    163             SkDebugfDumper dumper;
    164             SkDumpCanvas dumpCanvas(&dumper);
    165             dumpCanvas.drawPicture(pict);
    166         }
    167 #endif
    168 
    169         // This used to re-record the sub-picture and redraw the parent
    170         // A capability that is now forbidden!
    171 
    172         SkRandom rand(SampleCode::GetAnimTime());
    173         canvas->translate(SkIntToScalar(10), SkIntToScalar(250));
    174         canvas->drawPicture(fPicture);
    175         delayInval(500);
    176     }
    177 
    178 private:
    179     #define INVAL_ALL_TYPE  "inval-all"
    180 
    181     void delayInval(SkMSec delay) {
    182         (new SkEvent(INVAL_ALL_TYPE, this->getSinkID()))->postDelay(delay);
    183     }
    184 
    185     virtual bool onEvent(const SkEvent& evt) {
    186         if (evt.isType(INVAL_ALL_TYPE)) {
    187             this->inval(NULL);
    188             return true;
    189         }
    190         return this->INHERITED::onEvent(evt);
    191     }
    192 
    193     SkPicture*  fPicture;
    194     SkPicture*  fSubPicture;
    195 
    196     typedef SampleView INHERITED;
    197 };
    198 
    199 //////////////////////////////////////////////////////////////////////////////
    200 
    201 static SkView* MyFactory() { return new PictureView; }
    202 static SkViewRegister reg(MyFactory);
    203