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