747c31e296
Moves the (SkRect + flags) struct into SkImageFilter_Base with protected access only. Base constructor and all src/effects/imagefilters Make functions now take a "const SkRect*" instead. CropRect is still what's stored and used by filter implementations during filterImage(), but it's no longer publicly available. The SkImageFilters factory implementations now can go straight to the Make functions in src/effects/imagefilters instead of wrapping its "const SkRect*" in an SkImageFilter::CropRect. Bug: skia:9296, skia:11230 Change-Id: I2c62f42031910ec405623d4519c8a434cd2b3bdd Reviewed-on: https://skia-review.googlesource.com/c/skia/+/361496 Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org> Reviewed-by: Mike Reed <reed@google.com> Auto-Submit: Michael Ludwig <michaelludwig@google.com>
211 lines
6.8 KiB
C++
211 lines
6.8 KiB
C++
/*
|
|
* Copyright 2013 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "gm/gm.h"
|
|
#include "include/core/SkBitmap.h"
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkColor.h"
|
|
#include "include/core/SkImage.h"
|
|
#include "include/core/SkImageFilter.h"
|
|
#include "include/core/SkMatrix.h"
|
|
#include "include/core/SkPaint.h"
|
|
#include "include/core/SkRect.h"
|
|
#include "include/core/SkRefCnt.h"
|
|
#include "include/core/SkScalar.h"
|
|
#include "include/core/SkSize.h"
|
|
#include "include/core/SkString.h"
|
|
#include "include/effects/SkImageFilters.h"
|
|
#include "src/core/SkImageFilter_Base.h"
|
|
#include "tools/ToolUtils.h"
|
|
|
|
#include <utility>
|
|
|
|
#define WIDTH 600
|
|
#define HEIGHT 100
|
|
#define MARGIN 12
|
|
|
|
class OffsetImageFilterGM : public skiagm::GM {
|
|
public:
|
|
OffsetImageFilterGM() {
|
|
this->setBGColor(0xFF000000);
|
|
}
|
|
|
|
protected:
|
|
SkString onShortName() override {
|
|
return SkString("offsetimagefilter");
|
|
}
|
|
|
|
SkISize onISize() override {
|
|
return SkISize::Make(WIDTH, HEIGHT);
|
|
}
|
|
|
|
void onOnceBeforeDraw() override {
|
|
fBitmap = ToolUtils::create_string_image(80, 80, 0xD000D000, 15, 65, 96, "e");
|
|
|
|
fCheckerboard = ToolUtils::create_checkerboard_image(80, 80, 0xFFA0A0A0, 0xFF404040, 8);
|
|
}
|
|
|
|
void onDraw(SkCanvas* canvas) override {
|
|
canvas->clear(SK_ColorBLACK);
|
|
SkPaint paint;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
sk_sp<SkImage> image = (i & 0x01) ? fCheckerboard : fBitmap;
|
|
SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
|
|
i * 8,
|
|
image->width() - i * 8,
|
|
image->height() - i * 12);
|
|
sk_sp<SkImageFilter> tileInput(SkImageFilters::Image(image));
|
|
SkScalar dx = SkIntToScalar(i*5);
|
|
SkScalar dy = SkIntToScalar(i*10);
|
|
paint.setImageFilter(SkImageFilters::Offset(dx, dy, std::move(tileInput), &cropRect));
|
|
DrawClippedImage(canvas, image.get(), paint, 1, cropRect);
|
|
canvas->translate(SkIntToScalar(image->width() + MARGIN), 0);
|
|
}
|
|
|
|
SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
|
|
paint.setImageFilter(SkImageFilters::Offset(-5, -10, nullptr, &cropRect));
|
|
DrawClippedImage(canvas, fBitmap.get(), paint, 2, cropRect);
|
|
}
|
|
private:
|
|
static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint,
|
|
SkScalar scale, const SkIRect& cropRect) {
|
|
SkRect clipRect = SkRect::MakeIWH(image->width(), image->height());
|
|
|
|
canvas->save();
|
|
canvas->clipRect(clipRect);
|
|
canvas->scale(scale, scale);
|
|
canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
|
|
canvas->restore();
|
|
|
|
// Draw a boundary rect around the intersection of the clip rect and crop rect.
|
|
SkRect cropRectFloat;
|
|
SkMatrix::Scale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect));
|
|
if (clipRect.intersect(cropRectFloat)) {
|
|
SkPaint strokePaint;
|
|
strokePaint.setStyle(SkPaint::kStroke_Style);
|
|
strokePaint.setStrokeWidth(2);
|
|
strokePaint.setColor(SK_ColorRED);
|
|
canvas->drawRect(clipRect, strokePaint);
|
|
}
|
|
}
|
|
|
|
sk_sp<SkImage> fBitmap, fCheckerboard;
|
|
|
|
using INHERITED = skiagm::GM;
|
|
};
|
|
DEF_GM( return new OffsetImageFilterGM; )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
class SimpleOffsetImageFilterGM : public skiagm::GM {
|
|
public:
|
|
SimpleOffsetImageFilterGM() {}
|
|
|
|
protected:
|
|
SkString onShortName() override {
|
|
return SkString("simple-offsetimagefilter");
|
|
}
|
|
|
|
SkISize onISize() override { return SkISize::Make(640, 200); }
|
|
|
|
void doDraw(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imgf,
|
|
const SkIRect* cropR = nullptr, const SkRect* clipR = nullptr) {
|
|
SkPaint p;
|
|
|
|
if (clipR) {
|
|
p.setColor(0xFF00FF00);
|
|
p.setStyle(SkPaint::kStroke_Style);
|
|
canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
|
|
p.setStyle(SkPaint::kFill_Style);
|
|
}
|
|
|
|
// Visualize the crop rect for debugging
|
|
if (imgf && cropR) {
|
|
p.setColor(0x66FF00FF);
|
|
p.setStyle(SkPaint::kStroke_Style);
|
|
|
|
SkRect cr = SkRect::Make(*cropR).makeInset(SK_ScalarHalf, SK_ScalarHalf);
|
|
canvas->drawRect(cr, p);
|
|
p.setStyle(SkPaint::kFill_Style);
|
|
}
|
|
|
|
p.setColor(0x660000FF);
|
|
canvas->drawRect(r, p);
|
|
|
|
if (clipR) {
|
|
canvas->save();
|
|
canvas->clipRect(*clipR);
|
|
}
|
|
if (imgf) {
|
|
p.setImageFilter(std::move(imgf));
|
|
}
|
|
p.setColor(0x66FF0000);
|
|
canvas->drawRect(r, p);
|
|
|
|
if (clipR) {
|
|
canvas->restore();
|
|
}
|
|
}
|
|
|
|
void onDraw(SkCanvas* canvas) override {
|
|
SkIRect cr0 = SkIRect::MakeWH(40, 40);
|
|
SkIRect cr1 = SkIRect::MakeWH(20, 20);
|
|
SkIRect cr2 = SkIRect::MakeXYWH(40, 0, 40, 40);
|
|
const SkRect r = SkRect::Make(cr0);
|
|
const SkRect r2 = SkRect::Make(cr2);
|
|
|
|
canvas->translate(40, 40);
|
|
|
|
canvas->save();
|
|
this->doDraw(canvas, r, nullptr);
|
|
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr));
|
|
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr0), &cr0);
|
|
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr), /* cropR */ nullptr, &r);
|
|
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr1), &cr1);
|
|
|
|
SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40);
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr), /* cropR */ nullptr, &clipR);
|
|
canvas->restore();
|
|
|
|
// 2nd row
|
|
canvas->translate(0, 80);
|
|
|
|
/*
|
|
* combos of clip and crop rects that align with src and dst
|
|
*/
|
|
|
|
// crop==clip==src
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &cr0, &r);
|
|
|
|
// crop==src, clip==dst
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &cr0, &r2);
|
|
|
|
// crop==dst, clip==src
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &cr2, &r);
|
|
|
|
// crop==clip==dst
|
|
canvas->translate(100, 0);
|
|
this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &cr2, &r2);
|
|
}
|
|
|
|
private:
|
|
using INHERITED = skiagm::GM;
|
|
};
|
|
DEF_GM( return new SimpleOffsetImageFilterGM; )
|