Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2013 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 "SkImage.h"
      9 #include "SkImageSource.h"
     10 #include "SkOffsetImageFilter.h"
     11 #include "SkSurface.h"
     12 #include "gm.h"
     13 #include "sk_tool_utils.h"
     14 
     15 #define WIDTH 600
     16 #define HEIGHT 100
     17 #define MARGIN 12
     18 
     19 class OffsetImageFilterGM : public skiagm::GM {
     20 public:
     21     OffsetImageFilterGM() {
     22         this->setBGColor(0xFF000000);
     23     }
     24 
     25 protected:
     26     SkString onShortName() override {
     27         return SkString("offsetimagefilter");
     28     }
     29 
     30     SkISize onISize() override {
     31         return SkISize::Make(WIDTH, HEIGHT);
     32     }
     33 
     34     void onOnceBeforeDraw() override {
     35         fBitmap = SkImage::MakeFromBitmap(
     36             sk_tool_utils::create_string_bitmap(80, 80, 0xD000D000, 15, 65, 96, "e"));
     37 
     38         fCheckerboard = SkImage::MakeFromBitmap(
     39             sk_tool_utils::create_checkerboard_bitmap(80, 80,
     40                                                       sk_tool_utils::color_to_565(0xFFA0A0A0),
     41                                                       sk_tool_utils::color_to_565(0xFF404040),
     42                                                       8));
     43     }
     44 
     45     void onDraw(SkCanvas* canvas) override {
     46         canvas->clear(SK_ColorBLACK);
     47         SkPaint paint;
     48 
     49         for (int i = 0; i < 4; i++) {
     50             sk_sp<SkImage> image = (i & 0x01) ? fCheckerboard : fBitmap;
     51             SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
     52                                                  i * 8,
     53                                                  image->width() - i * 8,
     54                                                  image->height() - i * 12);
     55             SkImageFilter::CropRect rect(SkRect::Make(cropRect));
     56             sk_sp<SkImageFilter> tileInput(SkImageSource::Make(image));
     57             SkScalar dx = SkIntToScalar(i*5);
     58             SkScalar dy = SkIntToScalar(i*10);
     59             paint.setImageFilter(SkOffsetImageFilter::Make(dx, dy, std::move(tileInput), &rect));
     60             DrawClippedImage(canvas, image.get(), paint, 1, cropRect);
     61             canvas->translate(SkIntToScalar(image->width() + MARGIN), 0);
     62         }
     63 
     64         SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
     65         SkImageFilter::CropRect rect(SkRect::Make(cropRect));
     66         paint.setImageFilter(SkOffsetImageFilter::Make(-5, -10, nullptr, &rect));
     67         DrawClippedImage(canvas, fBitmap.get(), paint, 2, cropRect);
     68     }
     69 private:
     70     static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint,
     71                           SkScalar scale, const SkIRect& cropRect) {
     72         SkRect clipRect = SkRect::MakeIWH(image->width(), image->height());
     73 
     74         canvas->save();
     75         canvas->clipRect(clipRect);
     76         canvas->scale(scale, scale);
     77         canvas->drawImage(image, 0, 0, &paint);
     78         canvas->restore();
     79 
     80         // Draw a boundary rect around the intersection of the clip rect and crop rect.
     81         SkRect cropRectFloat;
     82         SkMatrix::MakeScale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect));
     83         if (clipRect.intersect(cropRectFloat)) {
     84             SkPaint strokePaint;
     85             strokePaint.setStyle(SkPaint::kStroke_Style);
     86             strokePaint.setStrokeWidth(2);
     87             strokePaint.setColor(SK_ColorRED);
     88             canvas->drawRect(clipRect, strokePaint);
     89         }
     90     }
     91 
     92     sk_sp<SkImage> fBitmap, fCheckerboard;
     93 
     94     typedef skiagm::GM INHERITED;
     95 };
     96 DEF_GM( return new OffsetImageFilterGM; )
     97 
     98 //////////////////////////////////////////////////////////////////////////////
     99 
    100 class SimpleOffsetImageFilterGM : public skiagm::GM {
    101 public:
    102     SimpleOffsetImageFilterGM() {}
    103 
    104 protected:
    105     SkString onShortName() override {
    106         return SkString("simple-offsetimagefilter");
    107     }
    108 
    109     SkISize onISize() override { return SkISize::Make(640, 200); }
    110 
    111     void doDraw(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imgf,
    112                 const SkRect* clipR = nullptr) {
    113         SkPaint p;
    114 
    115         if (clipR) {
    116             p.setColor(0xFF00FF00);
    117             p.setStyle(SkPaint::kStroke_Style);
    118             canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
    119             p.setStyle(SkPaint::kFill_Style);
    120         }
    121 
    122         if (imgf && imgf->cropRectIsSet()) {
    123             SkImageFilter::CropRect cr = imgf->getCropRect();
    124 
    125             p.setColor(0x66FF00FF);
    126             p.setStyle(SkPaint::kStroke_Style);
    127             canvas->drawRect(cr.rect().makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
    128             p.setStyle(SkPaint::kFill_Style);
    129         }
    130 
    131         p.setColor(0x660000FF);
    132         canvas->drawRect(r, p);
    133 
    134         if (clipR) {
    135             canvas->save();
    136             canvas->clipRect(*clipR);
    137         }
    138         if (imgf) {
    139             p.setImageFilter(std::move(imgf));
    140         }
    141         p.setColor(0x66FF0000);
    142         canvas->drawRect(r, p);
    143 
    144         if (clipR) {
    145             canvas->restore();
    146         }
    147     }
    148 
    149     void onDraw(SkCanvas* canvas) override {
    150         const SkRect r = SkRect::MakeWH(40, 40);
    151         SkImageFilter::CropRect cr0(r);
    152         SkImageFilter::CropRect cr1(SkRect::MakeWH(20, 20));
    153         const SkRect r2 = SkRect::MakeXYWH(40, 0, 40, 40);
    154         SkImageFilter::CropRect cr2(r2);
    155 
    156         canvas->translate(40, 40);
    157 
    158         canvas->save();
    159         this->doDraw(canvas, r, nullptr);
    160 
    161         canvas->translate(100, 0);
    162         this->doDraw(canvas, r, SkOffsetImageFilter::Make(20, 20, nullptr));
    163 
    164         canvas->translate(100, 0);
    165         this->doDraw(canvas, r, SkOffsetImageFilter::Make(20, 20, nullptr, &cr0));
    166 
    167         canvas->translate(100, 0);
    168         this->doDraw(canvas, r, SkOffsetImageFilter::Make(20, 20, nullptr), &r);
    169 
    170         canvas->translate(100, 0);
    171         this->doDraw(canvas, r, SkOffsetImageFilter::Make(20, 20, nullptr, &cr1));
    172 
    173         SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40);
    174         canvas->translate(100, 0);
    175         this->doDraw(canvas, r, SkOffsetImageFilter::Make(20, 20, nullptr, nullptr), &clipR);
    176         canvas->restore();
    177 
    178         // 2nd row
    179         canvas->translate(0, 80);
    180 
    181         /*
    182          *  combos of clip and crop rects that align with src and dst
    183          */
    184 
    185         // crop==clip==src
    186         this->doDraw(canvas, r, SkOffsetImageFilter::Make(40, 0, nullptr, &cr0), &r);
    187 
    188         // crop==src, clip==dst
    189         canvas->translate(100, 0);
    190         this->doDraw(canvas, r, SkOffsetImageFilter::Make(40, 0, nullptr, &cr0), &r2);
    191 
    192         // crop==dst, clip==src
    193         canvas->translate(100, 0);
    194         this->doDraw(canvas, r, SkOffsetImageFilter::Make(40, 0, nullptr, &cr2), &r);
    195 
    196         // crop==clip==dst
    197         canvas->translate(100, 0);
    198         this->doDraw(canvas, r, SkOffsetImageFilter::Make(40, 0, nullptr, &cr2), &r2);
    199     }
    200 
    201 private:
    202     typedef skiagm::GM INHERITED;
    203 };
    204 DEF_GM( return new SimpleOffsetImageFilterGM; )
    205