Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2014 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 "SkPaint.h"
     11 #include "SkPicture.h"
     12 #include "SkPictureRecorder.h"
     13 #include "SkShader.h"
     14 
     15 static const SkScalar kPictureSize = SK_Scalar1;
     16 static const SkScalar kFillSize = 100;
     17 static const unsigned kRowSize = 6;
     18 
     19 static const struct {
     20     SkScalar x, y, w, h;
     21     SkScalar offsetX, offsetY;
     22 } tiles[] = {
     23     {      0,      0,    1,    1,      0,    0 },
     24     {  -0.5f,  -0.5f,    1,    1,      0,    0 },
     25     {   0.5f,   0.5f,    1,    1,      0,    0 },
     26 
     27     {      0,      0, 1.5f, 1.5f,      0,    0 },
     28     {  -0.5f,  -0.5f, 1.5f, 1.5f,      0,    0 },
     29     {   0.5f,   0.5f, 1.5f, 1.5f,      0,    0 },
     30 
     31     {      0,      0, 0.5f, 0.5f,      0,    0 },
     32     {  0.25f,  0.25f, 0.5f, 0.5f,      0,    0 },
     33     { -0.25f, -0.25f, 0.5f, 0.5f,      0,    0 },
     34 
     35     {      0,      0,    1,    1,   0.5f, 0.5f },
     36     {  -0.5f,  -0.5f,    1,    1,   0.5f, 0.5f },
     37     {   0.5f,   0.5f,    1,    1,   0.5f, 0.5f },
     38 
     39     {      0,      0, 1.5f, 1.5f,   0.5f, 0.5f },
     40     {  -0.5f,  -0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
     41     {   0.5f,   0.5f, 1.5f, 1.5f,   0.5f, 0.5f },
     42 
     43     {      0,      0, 1.5f,    1,      0,    0 },
     44     {  -0.5f,  -0.5f, 1.5f,    1,      0,    0 },
     45     {   0.5f,   0.5f, 1.5f,    1,      0,    0 },
     46 
     47     {      0,      0, 0.5f,    1,      0,    0 },
     48     {  0.25f,  0.25f, 0.5f,    1,      0,    0 },
     49     { -0.25f, -0.25f, 0.5f,    1,      0,    0 },
     50 
     51     {      0,      0,    1, 1.5f,      0,    0 },
     52     {  -0.5f,  -0.5f,    1, 1.5f,      0,    0 },
     53     {   0.5f,   0.5f,    1, 1.5f,      0,    0 },
     54 
     55     {      0,      0,    1, 0.5f,      0,    0 },
     56     {  0.25f,  0.25f,    1, 0.5f,      0,    0 },
     57     { -0.25f, -0.25f,    1, 0.5f,      0,    0 },
     58 };
     59 
     60 static void draw_scene(SkCanvas* canvas, SkScalar pictureSize) {
     61     canvas->clear(SK_ColorWHITE);
     62 
     63     SkPaint paint;
     64     paint.setColor(SK_ColorGREEN);
     65     paint.setStyle(SkPaint::kFill_Style);
     66     paint.setAntiAlias(true);
     67 
     68     canvas->drawCircle(pictureSize / 4, pictureSize / 4, pictureSize / 4, paint);
     69     canvas->drawRect(SkRect::MakeXYWH(pictureSize / 2, pictureSize / 2,
     70                                       pictureSize / 2, pictureSize / 2), paint);
     71 
     72     paint.setColor(SK_ColorRED);
     73     canvas->drawLine(pictureSize / 2, pictureSize * 1 / 3,
     74                      pictureSize / 2, pictureSize * 2 / 3, paint);
     75     canvas->drawLine(pictureSize * 1 / 3, pictureSize / 2,
     76                      pictureSize * 2 / 3, pictureSize / 2, paint);
     77 
     78     paint.setColor(SK_ColorBLACK);
     79     paint.setStyle(SkPaint::kStroke_Style);
     80     canvas->drawRect(SkRect::MakeWH(pictureSize, pictureSize), paint);
     81 }
     82 
     83 class PictureShaderTileGM : public skiagm::GM {
     84 protected:
     85 
     86     SkString onShortName() override {
     87         return SkString("pictureshadertile");
     88     }
     89 
     90     SkISize onISize() override {
     91         return SkISize::Make(800, 600);
     92     }
     93 
     94     void onOnceBeforeDraw() override {
     95         SkPictureRecorder recorder;
     96         SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize);
     97         draw_scene(pictureCanvas, kPictureSize);
     98         SkAutoTUnref<SkPicture> picture(recorder.endRecording());
     99 
    100         SkPoint offset = SkPoint::Make(100, 100);
    101         pictureCanvas = recorder.beginRecording(SkRect::MakeXYWH(offset.x(), offset.y(),
    102                                                                  kPictureSize, kPictureSize));
    103         pictureCanvas->translate(offset.x(), offset.y());
    104         draw_scene(pictureCanvas, kPictureSize);
    105         SkAutoTUnref<SkPicture> offsetPicture(recorder.endRecording());
    106 
    107         for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
    108             SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
    109                                            tiles[i].y * kPictureSize,
    110                                            tiles[i].w * kPictureSize,
    111                                            tiles[i].h * kPictureSize);
    112             SkMatrix localMatrix;
    113             localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
    114                                      tiles[i].offsetY * kPictureSize);
    115             localMatrix.postScale(kFillSize / (2 * kPictureSize),
    116                                   kFillSize / (2 * kPictureSize));
    117 
    118             SkPicture* picturePtr = picture.get();
    119             SkRect* tilePtr = &tile;
    120 
    121             if (tile == SkRect::MakeWH(kPictureSize, kPictureSize)) {
    122                 // When the tile == picture bounds, exercise the picture + offset path.
    123                 picturePtr = offsetPicture.get();
    124                 tilePtr = nullptr;
    125             }
    126 
    127             fShaders[i].reset(SkShader::CreatePictureShader(picturePtr,
    128                                                             SkShader::kRepeat_TileMode,
    129                                                             SkShader::kRepeat_TileMode,
    130                                                             &localMatrix,
    131                                                             tilePtr));
    132         }
    133     }
    134 
    135     void onDraw(SkCanvas* canvas) override {
    136         canvas->clear(SK_ColorBLACK);
    137 
    138         SkPaint paint;
    139         paint.setStyle(SkPaint::kFill_Style);
    140 
    141         for (unsigned i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
    142             paint.setShader(fShaders[i]);
    143 
    144             canvas->save();
    145             canvas->translate((i % kRowSize) * kFillSize * 1.1f,
    146                               (i / kRowSize) * kFillSize * 1.1f);
    147             canvas->drawRect(SkRect::MakeWH(kFillSize, kFillSize), paint);
    148             canvas->restore();
    149         }
    150     }
    151 
    152 private:
    153     SkAutoTUnref<SkShader> fShaders[SK_ARRAY_COUNT(tiles)];
    154 
    155     typedef GM INHERITED;
    156 };
    157 
    158 DEF_GM(return new PictureShaderTileGM;)
    159