blob: b7be53e43da4493cf8f44d54b5a07c9497ad02aa [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"
Michael Ludwig898bbfa2019-08-02 15:21:23 -040025#include "include/effects/SkImageFilters.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040026#include "tools/ToolUtils.h"
Mike Reed77e487d2017-11-09 21:50:20 +000027
senorblanco@chromium.org53333002013-12-12 23:28:52 +000028// This GM exercises the SkPictureImageFilter ImageFilter class.
29
robertphillips5ff17b12016-03-28 13:13:42 -070030static void fill_rect_filtered(SkCanvas* canvas,
31 const SkRect& clipRect,
32 sk_sp<SkImageFilter> filter) {
33 SkPaint paint;
34 paint.setImageFilter(filter);
35 canvas->save();
36 canvas->clipRect(clipRect);
37 canvas->drawPaint(paint);
38 canvas->restore();
39}
40
41static sk_sp<SkPicture> make_picture() {
42 SkPictureRecorder recorder;
43 SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
robertphillips5ff17b12016-03-28 13:13:42 -070044 SkPaint paint;
robertphillips5ff17b12016-03-28 13:13:42 -070045 paint.setColor(0xFFFFFFFF);
Mike Kleinea3f0142019-03-20 11:12:10 -050046 SkFont font(ToolUtils::create_portable_typeface(), 96.0f);
Hal Canarydf2d27e2019-01-08 09:38:02 -050047 canvas->drawString("e", 20.0f, 70.0f, font, paint);
robertphillips5ff17b12016-03-28 13:13:42 -070048 return recorder.finishRecordingAsPicture();
49}
50
robertphillips54ef1a72016-04-13 10:55:07 -070051// Create a picture that will draw LCD text
52static sk_sp<SkPicture> make_LCD_picture() {
53 SkPictureRecorder recorder;
54 SkCanvas* canvas = recorder.beginRecording(100, 100, nullptr, 0);
55 canvas->clear(SK_ColorTRANSPARENT);
56 SkPaint paint;
robertphillips54ef1a72016-04-13 10:55:07 -070057 paint.setColor(0xFFFFFFFF);
58 // this has to be small enough that it doesn't become a path
Mike Kleinea3f0142019-03-20 11:12:10 -050059 SkFont font(ToolUtils::create_portable_typeface(), 36.0f);
Hal Canarydf2d27e2019-01-08 09:38:02 -050060 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
61 canvas->drawString("e", 20.0f, 70.0f, font, paint);
robertphillips54ef1a72016-04-13 10:55:07 -070062 return recorder.finishRecordingAsPicture();
63}
64
senorblanco@chromium.org53333002013-12-12 23:28:52 +000065class PictureImageFilterGM : public skiagm::GM {
66public:
robertphillips5ff17b12016-03-28 13:13:42 -070067 PictureImageFilterGM() { }
senorblanco@chromium.org53333002013-12-12 23:28:52 +000068
69protected:
mtklein36352bf2015-03-25 18:17:31 -070070 SkString onShortName() override {
senorblanco@chromium.org53333002013-12-12 23:28:52 +000071 return SkString("pictureimagefilter");
72 }
73
mtklein36352bf2015-03-25 18:17:31 -070074 SkISize onISize() override { return SkISize::Make(600, 300); }
senorblanco@chromium.org53333002013-12-12 23:28:52 +000075
mtklein36352bf2015-03-25 18:17:31 -070076 void onOnceBeforeDraw() override {
robertphillips5ff17b12016-03-28 13:13:42 -070077 fPicture = make_picture();
robertphillips54ef1a72016-04-13 10:55:07 -070078 fLCDPicture = make_LCD_picture();
senorblanco@chromium.org53333002013-12-12 23:28:52 +000079 }
80
Mike Reed77e487d2017-11-09 21:50:20 +000081 sk_sp<SkImageFilter> make(sk_sp<SkPicture> pic, SkRect r, SkFilterQuality fq) {
82 SkISize dim = { SkScalarRoundToInt(r.width()), SkScalarRoundToInt(r.height()) };
83 auto img = SkImage::MakeFromPicture(pic, dim, nullptr, nullptr,
84 SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
Michael Ludwig898bbfa2019-08-02 15:21:23 -040085 return SkImageFilters::Image(img, r, r, fq);
Mike Reed77e487d2017-11-09 21:50:20 +000086 }
87 sk_sp<SkImageFilter> make(SkFilterQuality fq) {
88 return make(fPicture, fPicture->cullRect(), fq);
89 }
90
mtklein36352bf2015-03-25 18:17:31 -070091 void onDraw(SkCanvas* canvas) override {
robertphillips54ef1a72016-04-13 10:55:07 -070092 canvas->clear(SK_ColorGRAY);
senorblanco@chromium.org53333002013-12-12 23:28:52 +000093 {
94 SkRect srcRect = SkRect::MakeXYWH(20, 20, 30, 30);
95 SkRect emptyRect = SkRect::MakeXYWH(20, 20, 0, 0);
96 SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
Michael Ludwig898bbfa2019-08-02 15:21:23 -040097 sk_sp<SkImageFilter> pictureSource(SkImageFilters::Picture(fPicture));
98 sk_sp<SkImageFilter> pictureSourceSrcRect(SkImageFilters::Picture(fPicture, srcRect));
99 sk_sp<SkImageFilter> pictureSourceEmptyRect(SkImageFilters::Picture(fPicture,
100 emptyRect));
Mike Reed77e487d2017-11-09 21:50:20 +0000101 sk_sp<SkImageFilter> pictureSourceResampled = make(kLow_SkFilterQuality);
102 sk_sp<SkImageFilter> pictureSourcePixelated = make(kNone_SkFilterQuality);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000103
Justin Novosad52340752014-12-02 14:50:56 -0500104 canvas->save();
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000105 // Draw the picture unscaled.
robertphillips5ff17b12016-03-28 13:13:42 -0700106 fill_rect_filtered(canvas, bounds, pictureSource);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000107 canvas->translate(SkIntToScalar(100), 0);
108
109 // Draw an unscaled subset of the source picture.
robertphillips5ff17b12016-03-28 13:13:42 -0700110 fill_rect_filtered(canvas, bounds, pictureSourceSrcRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000111 canvas->translate(SkIntToScalar(100), 0);
112
113 // Draw the picture to an empty rect (should draw nothing).
robertphillips5ff17b12016-03-28 13:13:42 -0700114 fill_rect_filtered(canvas, bounds, pictureSourceEmptyRect);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000115 canvas->translate(SkIntToScalar(100), 0);
Justin Novosad52340752014-12-02 14:50:56 -0500116
robertphillips54ef1a72016-04-13 10:55:07 -0700117 // Draw the LCD picture to a layer
118 {
119 SkPaint stroke;
120 stroke.setStyle(SkPaint::kStroke_Style);
121
122 canvas->drawRect(bounds, stroke);
123
124 SkPaint paint;
Mike Reed77e487d2017-11-09 21:50:20 +0000125 paint.setImageFilter(make(fLCDPicture, fPicture->cullRect(), kNone_SkFilterQuality));
robertphillips54ef1a72016-04-13 10:55:07 -0700126
127 canvas->scale(4, 4);
128 canvas->translate(-0.9f*srcRect.fLeft, -2.45f*srcRect.fTop);
129
Florin Malita07e4adf2019-01-07 16:34:18 -0500130 canvas->saveLayer(&bounds, &paint);
robertphillips54ef1a72016-04-13 10:55:07 -0700131 canvas->restore();
132 }
133
Justin Novosad52340752014-12-02 14:50:56 -0500134 canvas->restore();
135
136 // Draw the picture scaled
137 canvas->translate(0, SkIntToScalar(100));
138 canvas->scale(200 / srcRect.width(), 200 / srcRect.height());
139 canvas->translate(-srcRect.fLeft, -srcRect.fTop);
robertphillips5ff17b12016-03-28 13:13:42 -0700140 fill_rect_filtered(canvas, srcRect, pictureSource);
Justin Novosad52340752014-12-02 14:50:56 -0500141
142 // Draw the picture scaled, but rasterized at original resolution
143 canvas->translate(srcRect.width(), 0);
robertphillips5ff17b12016-03-28 13:13:42 -0700144 fill_rect_filtered(canvas, srcRect, pictureSourceResampled);
junovf3c78cc2014-12-09 13:07:22 -0800145
146 // Draw the picture scaled, pixelated
147 canvas->translate(srcRect.width(), 0);
robertphillips5ff17b12016-03-28 13:13:42 -0700148 fill_rect_filtered(canvas, srcRect, pictureSourcePixelated);
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000149 }
150 }
151
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000152private:
reedca2622b2016-03-18 07:25:55 -0700153 sk_sp<SkPicture> fPicture;
robertphillips54ef1a72016-04-13 10:55:07 -0700154 sk_sp<SkPicture> fLCDPicture;
robertphillips5ff17b12016-03-28 13:13:42 -0700155
senorblanco@chromium.org53333002013-12-12 23:28:52 +0000156 typedef GM INHERITED;
157};
158
159///////////////////////////////////////////////////////////////////////////////
160
161DEF_GM( return new PictureImageFilterGM; )