Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2015 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 "SkImage.h"
     11 #include "SkSurface.h"
     12 #include "SkTArray.h"
     13 
     14 class ImageScaleAlignedGM : public skiagm::GM {
     15 protected:
     16     void onOnceBeforeDraw() override {
     17         const SkVector vectors[] = { { 1, 0 }, { 0, 1 } };
     18 
     19         for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) {
     20            auto& set = fSets.push_back();
     21 
     22            set.fVector = vectors[i];
     23            set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
     24            set.fScales.push_back() = 1;
     25            set.fImages.push_back() = MakeImage(vectors[i], SK_ColorRED);
     26            set.fScales.push_back() = kStretchFactor;
     27            set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
     28            set.fScales.push_back() = 1;
     29         }
     30     }
     31 
     32     SkString onShortName() override {
     33         return SkString("image_scale_aligned");
     34     }
     35 
     36     SkISize onISize() override {
     37         return SkISize::Make(580, 780);
     38     }
     39 
     40     void onDraw(SkCanvas* canvas) override {
     41         struct {
     42             SkPoint offset;
     43             SkVector scale;
     44         } cfgs[] = {
     45             {{  10,    10    }, { 1, 1 }},
     46             {{ 300.5f, 10    }, { 1, 1 }},
     47             {{  10,    200.5f }, { 1, 1 }},
     48             {{ 300.5f, 200.5f }, { 1, 1 }},
     49 
     50             {{  10.5f, 400.5f }, {  1,  1 }},
     51             {{ 550.5f, 400.5f }, { -1,  1 }},
     52             {{  10.5f, 750.5f }, {  1, -1 }},
     53             {{ 550.5f, 750.5f }, { -1, -1 }},
     54         };
     55 
     56         for (size_t i = 0; i < SK_ARRAY_COUNT(cfgs); ++i) {
     57             SkAutoCanvasRestore acr(canvas, true);
     58             canvas->translate(cfgs[i].offset.x(), cfgs[i].offset.y());
     59             canvas->scale(cfgs[i].scale.x(), cfgs[i].scale.y());
     60             drawSets(canvas);
     61         }
     62     }
     63 
     64 private:
     65     struct ImageSet {
     66         SkSTArray<3, sk_sp<SkImage>, true>  fImages;
     67         SkSTArray<3, SkScalar>              fScales;
     68         SkVector                            fVector;
     69     };
     70 
     71     static sk_sp<SkImage> MakeImage(const SkVector& vec, SkColor color) {
     72         const SkPoint start = SkPoint::Make(vec.y() * kSegLen / 2, vec.x() * kSegLen / 2);
     73         const SkPoint end   = SkPoint::Make(start.x() + vec.x() * (kSegLen - 1),
     74                                             start.y() + vec.y() * (kSegLen - 1));
     75 
     76         auto surface(SkSurface::MakeRasterN32Premul(kSegLen, kSegLen));
     77         surface->getCanvas()->clear(SK_ColorTRANSPARENT);
     78 
     79         SkPaint paint;
     80         paint.setAntiAlias(true);
     81         const SkRect border = SkRect::MakeIWH(kSegLen, kSegLen).makeInset(.5f, .5f);
     82         paint.setColor(SK_ColorBLUE);
     83         paint.setStyle(SkPaint::kStroke_Style);
     84         surface->getCanvas()->drawRect(border, paint);
     85 
     86         paint.setColor(SK_ColorBLACK);
     87         surface->getCanvas()->drawLine(start.x(), start.y(), end.x(), end.y(), paint);
     88 
     89         paint.reset();
     90         paint.setColor(color);
     91         const SkPoint pts[] = { start, end };
     92         surface->getCanvas()->drawPoints(SkCanvas::kPoints_PointMode, 2, pts, paint);
     93 
     94         return surface->makeImageSnapshot();
     95     }
     96 
     97     void drawSets(SkCanvas* canvas) const {
     98         SkAutoCanvasRestore acr(canvas, true);
     99 
    100         const SkFilterQuality filters[] = {
    101             kNone_SkFilterQuality,
    102             kLow_SkFilterQuality,
    103             kMedium_SkFilterQuality,
    104             kHigh_SkFilterQuality
    105         };
    106         const bool AAs[] = { false, true };
    107 
    108         SkPaint paint;
    109         for (int i = 0; i < fSets.count(); ++i) {
    110             auto& set = fSets[i];
    111             SkPoint lastPt;
    112             for (size_t j = 0; j < SK_ARRAY_COUNT(AAs); ++j) {
    113                 paint.setAntiAlias(AAs[j]);
    114                 for (size_t k = 0; k < SK_ARRAY_COUNT(filters); ++k) {
    115                     paint.setFilterQuality(filters[k]);
    116                     lastPt = drawSet(canvas, set, paint);
    117                     canvas->translate((kSegLen + 4) * set.fVector.y(),
    118                                       (kSegLen + 4) * set.fVector.x());
    119                 }
    120             }
    121             canvas->translate(lastPt.x() + kSegLen,
    122                 - SkIntToScalar(kSegLen + 4) * SK_ARRAY_COUNT(filters) * SK_ARRAY_COUNT(AAs));
    123         }
    124     }
    125 
    126     SkPoint drawSet(SkCanvas* canvas, const ImageSet& set, const SkPaint& paint) const {
    127         SkASSERT(set.fImages.count() == set.fScales.count());
    128 
    129         SkPoint pt = SkPoint::Make(0, 0);
    130         for (int i = 0; i < set.fImages.count(); ++i) {
    131             auto& img = set.fImages[i];
    132             const SkRect dst =
    133                 SkRect::MakeXYWH(pt.x(), pt.y(),
    134                     img->width() * (1 + (set.fScales[i] - 1) * set.fVector.x()),
    135                     img->height() * (1 + (set.fScales[i] - 1) * set.fVector.y()));
    136 
    137             canvas->drawImageRect(img.get(), dst, &paint);
    138             pt.offset(dst.width() * set.fVector.x(), dst.height() * set.fVector.y());
    139         }
    140 
    141         return pt;
    142     }
    143 
    144     static constexpr unsigned  kSegLen = 15;
    145     static constexpr unsigned  kStretchFactor = 4;
    146     SkSTArray<2, ImageSet> fSets;
    147 
    148     typedef GM INHERITED;
    149 };
    150 
    151 DEF_GM(return new ImageScaleAlignedGM();)
    152