/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm.h"
#include "SkColorPriv.h"
#include "SkImageSource.h"
#include "SkMagnifierImageFilter.h"
#include "SkSurface.h"
static sk_sp<SkImage> make_image(GrContext* context, int size, GrSurfaceOrigin origin) {
if (context) {
SkImageInfo ii = SkImageInfo::Make(size, size, kN32_SkColorType, kPremul_SkAlphaType);
sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, 0,
origin, nullptr));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
canvas->clear(SK_ColorRED);
const struct {
SkPoint fPt;
SkColor fColor;
} rec[] = {
{ { 1.5f, 1.5f }, SK_ColorGREEN },
{ { 2.5f, 1.5f }, SK_ColorBLUE },
{ { 1.5f, 2.5f }, SK_ColorCYAN },
{ { 2.5f, 2.5f }, SK_ColorGRAY },
};
SkPaint paint;
for (const auto& r : rec) {
paint.setColor(r.fColor);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, &r.fPt, paint);
}
return surf->makeImageSnapshot();
} else {
SkBitmap bm;
bm.allocN32Pixels(size, size);
bm.eraseColor(SK_ColorRED);
*bm.getAddr32(1, 1) = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
*bm.getAddr32(2, 1) = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
*bm.getAddr32(1, 2) = SkPackARGB32(0xFF, 0x00, 0xFF, 0xFF);
*bm.getAddr32(2, 2) = SkPackARGB32(0xFF, 0x88, 0x88, 0x88);
return SkImage::MakeFromBitmap(bm);
}
}
/*
* This GM creates an image with a 2x2:
* Green | Blue
* ------------
* Cyan | Gray
* block of pixels in one corner of a 33x33 field. The 'srcRect' feature of the
* SkMagnifierImageFilter is then used to blow it up with different inset border widths.
*
* In GPU-mode we wind up drawing 4 rects:
*
* BottomLeft origin + 1-wide inset | TopLeft origin + 1-wide inset
* ----------------------------------------------------------------
* BottomLeft origin + 7-wide inset | TopLeft origin + 7-wide inset
*
* In Raster-mode the source origin isn't used.
*/
class SimpleMagnificationGM : public skiagm::GM {
public:
SimpleMagnificationGM() {
this->setBGColor(0xFFCCCCCC);
}
protected:
SkString onShortName() override {
return SkString("simple-magnification");
}
SkISize onISize() override {
return SkISize::Make(3*kPad+2*kImgSize, 3*kPad+2*kImgSize);
}
void draw(SkCanvas* canvas, sk_sp<SkImage> image, const SkIPoint& offset, int inset) {
sk_sp<SkImageFilter> imgSrc(SkImageSource::Make(std::move(image)));
SkRect srcRect = SkRect::MakeXYWH(1.0f, 1.0f, 2.0f, 2.0f);
sk_sp<SkImageFilter> magFilter(SkMagnifierImageFilter::Make(srcRect, inset, imgSrc));
SkPaint paint;
paint.setImageFilter(std::move(magFilter));
canvas->save();
canvas->translate(offset.fX, offset.fY);
SkRect rect = SkRect::MakeWH(kImgSize, kImgSize);
canvas->drawRect(rect, paint);
canvas->restore();
}
DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
GrContext* context = canvas->getGrContext();
sk_sp<SkImage> bottomLImg = make_image(context, kImgSize, kBottomLeft_GrSurfaceOrigin);
sk_sp<SkImage> topLImg = make_image(context, kImgSize, kTopLeft_GrSurfaceOrigin);
if (!bottomLImg || !topLImg) {
*errorMsg = "Could not load images. Did you forget to set the resourcePath?";
return DrawResult::kFail;
}
int bigOffset = 2 * kPad + kImgSize;
this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, kPad), 1);
this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, kPad), 1);
this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, bigOffset), 7);
this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, bigOffset), 7);
return DrawResult::kOk;
}
private:
static const int kImgSize = 33;
static const int kPad = 2;
typedef skiagm::GM INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_GM(return new SimpleMagnificationGM;)