blob: 38b58934feaf7b1fcfc3e3e7ba0e291f94da6806 [file] [log] [blame]
senorblanco@chromium.org53333002013-12-12 23:28:52 +00001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -04009#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
11#include "include/core/SkColorSpace.h"
12#include "include/core/SkFilterQuality.h"
13#include "include/core/SkFont.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkImage.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#include "include/core/SkImageFilter.h"
16#include "include/core/SkPaint.h"
17#include "include/core/SkPicture.h"
18#include "include/core/SkPictureRecorder.h"
19#include "include/core/SkRect.h"
20#include "include/core/SkRefCnt.h"
21#include "include/core/SkScalar.h"
22#include "include/core/SkSize.h"
23#include "include/core/SkString.h"
24#include "include/core/SkTypeface.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "include/effects/SkImageSource.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040026#include "include/effects/SkPictureImageFilter.h"
27#include "tools/ToolUtils.h"
Mike Reed77e487d2017-11-09 21:50:20 +000028
senorblanco@chromium.org53333002013-12-12 23:28:52 +000029// This GM exercises the SkPictureImageFilter ImageFilter class.
30
robertphillips5ff17b12016-03-28 13:13:42 -070031static void fill_rect_filtered(SkCanvas* canvas,
32 const SkRect& clipRect,
33 sk_sp<SkImageFilter> filter) {
34 SkPaint paint;
35 paint.setImageFilter(filter);
36 canvas->save();
37 canvas->clipRect(clipRect);
38 canvas->drawPaint(paint);
39 canvas->restore();
40}
41
42static sk_sp<SkPicture> make_picture() {
43 SkPictureRecorder recorder;
44 SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
robertphillips5ff17b12016-03-28 13:13:42 -070045 SkPaint paint;
robertphillips5ff17b12016-03-28 13:13:42 -070046 paint.setColor(0xFFFFFFFF);
Mike Kleinea3f0142019-03-20 11:12:10 -050047 SkFont font(ToolUtils::create_portable_typeface(), 96.0f);
Hal Canarydf2d27e2019-01-08 09:38:02 -050048 canvas->drawString("e", 20.0f, 70.0f, font, paint);
robertphillips5ff17b12016-03-28 13:13:42 -070049 return recorder.finishRecordingAsPicture();
50}
51
robertphillips54ef1a72016-04-13 10:55:07 -070052// Create a picture that will draw LCD text
53static sk_sp<SkPicture> make_LCD_picture() {
54 SkPictureRecorder recorder;
55 SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
56 canvas->clear(SK_ColorTRANSPARENT);
57 SkPaint paint;
robertphillips54ef1a72016-04-13 10:55:07 -070058 paint.setColor(0xFFFFFFFF);
59 // this has to be small enough that it doesn't become a path
Mike Kleinea3f0142019-03-20 11:12:10 -050060 SkFont font(ToolUtils::create_portable_typeface(), 36.0f);
Hal Canarydf2d27e2019-01-08 09:38:02 -050061 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
62 canvas->drawString("e", 20.0f, 70.0f, font, paint);
robertphillips54ef1a72016-04-13 10:55:07 -070063 return recorder.finishRecordingAsPicture();
64}
65
senorblanco@chromium.org53333002013-12-12 23:28:52 +000066class PictureImageFilterGM : public skiagm::GM {
67public:
robertphillips5ff17b12016-03-28 13:13:42 -070068 PictureImageFilterGM() { }
senorblanco@chromium.org53333002013-12-12 23:28:52 +000069
70protected:
mtklein36352bf2015-03-25 18:17:31 -070071 SkString onShortName() override {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000072 return SkString("pictureimagefilter");
73 }
74
mtklein36352bf2015-03-25 18:17:31 -070075 SkISize onISize() override { return SkISize::Make(600, 300); }
senorblanco@chromium.org53333002013-12-12 23:28:52 +000076
mtklein36352bf2015-03-25 18:17:31 -070077 void onOnceBeforeDraw() override {
robertphillips5ff17b12016-03-28 13:13:42 -070078 fPicture = make_picture();
robertphillips54ef1a72016-04-13 10:55:07 -070079 fLCDPicture = make_LCD_picture();
senorblanco@chromium.org53333002013-12-12 23:28:52 +000080 }
81
Mike Reed77e487d2017-11-09 21:50:20 +000082 sk_sp<SkImageFilter> make(sk_sp<SkPicture> pic, SkRect r, SkFilterQuality fq) {
83 SkISize dim = { SkScalarRoundToInt(r.width()), SkScalarRoundToInt(r.height()) };
84 auto img = SkImage::MakeFromPicture(pic, dim, nullptr, nullptr,
85 SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
86 return SkImageSource::Make(img, r, r, fq);
87 }
88 sk_sp<SkImageFilter> make(SkFilterQuality fq) {
89 return make(fPicture, fPicture->cullRect(), fq);
90 }
91
mtklein36352bf2015-03-25 18:17:31 -070092 void onDraw(SkCanvas* canvas) override {
robertphillips54ef1a72016-04-13 10:55:07 -070093 canvas->clear(SK_ColorGRAY);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000094 {
95 SkRect srcRect = SkRect::MakeXYWH(20, 20, 30, 30);
96 SkRect emptyRect = SkRect::MakeXYWH(20, 20, 0, 0);
97 SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
robertphillips5ff17b12016-03-28 13:13:42 -070098 sk_sp<SkImageFilter> pictureSource(SkPictureImageFilter::Make(fPicture));
99 sk_sp<SkImageFilter> pictureSourceSrcRect(SkPictureImageFilter::Make(fPicture,
100 srcRect));
101 sk_sp<SkImageFilter> pictureSourceEmptyRect(SkPictureImageFilter::Make(fPicture,
102 emptyRect));
Mike Reed77e487d2017-11-09 21:50:20 +0000103 sk_sp<SkImageFilter> pictureSourceResampled = make(kLow_SkFilterQuality);
104 sk_sp<SkImageFilter> pictureSourcePixelated = make(kNone_SkFilterQuality);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000105
Justin Novosad52340752014-12-02 14:50:56 -0500106 canvas->save();
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000107 // Draw the picture unscaled.
robertphillips5ff17b12016-03-28 13:13:42 -0700108 fill_rect_filtered(canvas, bounds, pictureSource);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000109 canvas->translate(SkIntToScalar(100), 0);
110
111 // Draw an unscaled subset of the source picture.
robertphillips5ff17b12016-03-28 13:13:42 -0700112 fill_rect_filtered(canvas, bounds, pictureSourceSrcRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000113 canvas->translate(SkIntToScalar(100), 0);
114
115 // Draw the picture to an empty rect (should draw nothing).
robertphillips5ff17b12016-03-28 13:13:42 -0700116 fill_rect_filtered(canvas, bounds, pictureSourceEmptyRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000117 canvas->translate(SkIntToScalar(100), 0);
Justin Novosad52340752014-12-02 14:50:56 -0500118
robertphillips54ef1a72016-04-13 10:55:07 -0700119 // Draw the LCD picture to a layer
120 {
121 SkPaint stroke;
122 stroke.setStyle(SkPaint::kStroke_Style);
123
124 canvas->drawRect(bounds, stroke);
125
126 SkPaint paint;
Mike Reed77e487d2017-11-09 21:50:20 +0000127 paint.setImageFilter(make(fLCDPicture, fPicture->cullRect(), kNone_SkFilterQuality));
robertphillips54ef1a72016-04-13 10:55:07 -0700128
129 canvas->scale(4, 4);
130 canvas->translate(-0.9f*srcRect.fLeft, -2.45f*srcRect.fTop);
131
Florin Malita07e4adf2019-01-07 16:34:18 -0500132 canvas->saveLayer(&bounds, &paint);
robertphillips54ef1a72016-04-13 10:55:07 -0700133 canvas->restore();
134 }
135
Justin Novosad52340752014-12-02 14:50:56 -0500136 canvas->restore();
137
138 // Draw the picture scaled
139 canvas->translate(0, SkIntToScalar(100));
140 canvas->scale(200 / srcRect.width(), 200 / srcRect.height());
141 canvas->translate(-srcRect.fLeft, -srcRect.fTop);
robertphillips5ff17b12016-03-28 13:13:42 -0700142 fill_rect_filtered(canvas, srcRect, pictureSource);
Justin Novosad52340752014-12-02 14:50:56 -0500143
144 // Draw the picture scaled, but rasterized at original resolution
145 canvas->translate(srcRect.width(), 0);
robertphillips5ff17b12016-03-28 13:13:42 -0700146 fill_rect_filtered(canvas, srcRect, pictureSourceResampled);
junovf3c78cc2014-12-09 13:07:22 -0800147
148 // Draw the picture scaled, pixelated
149 canvas->translate(srcRect.width(), 0);
robertphillips5ff17b12016-03-28 13:13:42 -0700150 fill_rect_filtered(canvas, srcRect, pictureSourcePixelated);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000151 }
152 }
153
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000154private:
reedca2622b2016-03-18 07:25:55 -0700155 sk_sp<SkPicture> fPicture;
robertphillips54ef1a72016-04-13 10:55:07 -0700156 sk_sp<SkPicture> fLCDPicture;
robertphillips5ff17b12016-03-28 13:13:42 -0700157
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000158 typedef GM INHERITED;
159};
160
161///////////////////////////////////////////////////////////////////////////////
162
163DEF_GM( return new PictureImageFilterGM; )