Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2017 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 #include "SkColorPriv.h"
     10 #include "SkImageSource.h"
     11 #include "SkMagnifierImageFilter.h"
     12 #include "SkSurface.h"
     13 
     14 static sk_sp<SkImage> make_image(GrContext* context, int size, GrSurfaceOrigin origin) {
     15     if (context) {
     16         SkImageInfo ii = SkImageInfo::Make(size, size, kN32_SkColorType, kPremul_SkAlphaType);
     17         sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, 0,
     18                                                           origin, nullptr));
     19         if (!surf) {
     20             return nullptr;
     21         }
     22 
     23         SkCanvas* canvas = surf->getCanvas();
     24 
     25         canvas->clear(SK_ColorRED);
     26         const struct {
     27             SkPoint fPt;
     28             SkColor fColor;
     29         } rec[] = {
     30             { { 1.5f, 1.5f }, SK_ColorGREEN },
     31             { { 2.5f, 1.5f }, SK_ColorBLUE },
     32             { { 1.5f, 2.5f }, SK_ColorCYAN },
     33             { { 2.5f, 2.5f }, SK_ColorGRAY },
     34         };
     35         SkPaint paint;
     36         for (const auto& r : rec) {
     37             paint.setColor(r.fColor);
     38             canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, &r.fPt, paint);
     39         }
     40         return surf->makeImageSnapshot();
     41     } else {
     42         SkBitmap bm;
     43         bm.allocN32Pixels(size, size);
     44         bm.eraseColor(SK_ColorRED);
     45         *bm.getAddr32(1, 1) = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
     46         *bm.getAddr32(2, 1) = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
     47         *bm.getAddr32(1, 2) = SkPackARGB32(0xFF, 0x00, 0xFF, 0xFF);
     48         *bm.getAddr32(2, 2) = SkPackARGB32(0xFF, 0x88, 0x88, 0x88);
     49 
     50         return SkImage::MakeFromBitmap(bm);
     51     }
     52 }
     53 
     54 /*
     55  * This GM creates an image with a 2x2:
     56  *    Green | Blue
     57  *    ------------
     58  *    Cyan  | Gray
     59  * block of pixels in one corner of a 33x33 field. The 'srcRect' feature of the
     60  * SkMagnifierImageFilter is then used to blow it up with different inset border widths.
     61  *
     62  * In GPU-mode we wind up drawing 4 rects:
     63  *
     64  *     BottomLeft origin + 1-wide inset | TopLeft origin + 1-wide inset
     65  *     ----------------------------------------------------------------
     66  *     BottomLeft origin + 7-wide inset | TopLeft origin + 7-wide inset
     67  *
     68  * In Raster-mode the source origin isn't used.
     69  */
     70 class SimpleMagnificationGM : public skiagm::GM {
     71 public:
     72     SimpleMagnificationGM() {
     73         this->setBGColor(0xFFCCCCCC);
     74     }
     75 
     76 protected:
     77     SkString onShortName() override {
     78         return SkString("simple-magnification");
     79     }
     80 
     81     SkISize onISize() override {
     82         return SkISize::Make(3*kPad+2*kImgSize, 3*kPad+2*kImgSize);
     83     }
     84 
     85     void draw(SkCanvas* canvas, sk_sp<SkImage> image, const SkIPoint& offset, int inset) {
     86         sk_sp<SkImageFilter> imgSrc(SkImageSource::Make(std::move(image)));
     87 
     88         SkRect srcRect = SkRect::MakeXYWH(1.0f, 1.0f, 2.0f, 2.0f);
     89         sk_sp<SkImageFilter> magFilter(SkMagnifierImageFilter::Make(srcRect, inset, imgSrc));
     90 
     91         SkPaint paint;
     92         paint.setImageFilter(std::move(magFilter));
     93 
     94         canvas->save();
     95         canvas->translate(offset.fX, offset.fY);
     96         SkRect rect = SkRect::MakeWH(kImgSize, kImgSize);
     97         canvas->drawRect(rect, paint);
     98 
     99         canvas->restore();
    100     }
    101 
    102     void onDraw(SkCanvas* canvas) override {
    103         GrContext* context = canvas->getGrContext();
    104 
    105         sk_sp<SkImage> bottomLImg = make_image(context, kImgSize, kBottomLeft_GrSurfaceOrigin);
    106         sk_sp<SkImage> topLImg = make_image(context, kImgSize, kTopLeft_GrSurfaceOrigin);
    107         if (!bottomLImg || !topLImg) {
    108             return;
    109         }
    110 
    111         int bigOffset = 2 * kPad + kImgSize;
    112 
    113         this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, kPad), 1);
    114         this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, kPad), 1);
    115         this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, bigOffset), 7);
    116         this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, bigOffset), 7);
    117     }
    118 
    119 private:
    120     static const int kImgSize = 33;
    121     static const int kPad = 2;
    122 
    123     typedef skiagm::GM INHERITED;
    124 };
    125 
    126 //////////////////////////////////////////////////////////////////////////////
    127 
    128 DEF_GM(return new SimpleMagnificationGM;)
    129