Flutter Engine
The Flutter Engine
xfermodeimagefilter.cpp
Go to the documentation of this file.
1/*
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
8#include "gm/gm.h"
16#include "include/core/SkRect.h"
19#include "include/core/SkSize.h"
23#include "tools/ToolUtils.h"
25
26#include <utility>
27
28#define WIDTH 600
29#define HEIGHT 700
30#define MARGIN 12
31
32namespace skiagm {
33
34class XfermodeImageFilterGM : public GM {
35public:
37 this->setBGColor(0xFF000000);
38 }
39
40protected:
41 SkString getName() const override { return SkString("xfermodeimagefilter"); }
42
43 SkISize getISize() override { return SkISize::Make(WIDTH, HEIGHT); }
44
45 void onOnceBeforeDraw() override {
46 fBitmap = ToolUtils::CreateStringBitmap(80, 80, 0xD000D000, 15, 65, 96, "e");
47
48 fCheckerboard = ToolUtils::create_checkerboard_image(80, 80, 0xFFA0A0A0, 0xFF404040, 8);
49 }
50
51 void onDraw(SkCanvas* canvas) override {
52 canvas->clear(SK_ColorBLACK);
54
55 const SkBlendMode gModes[] = {
68
86 };
87
88 int x = 0, y = 0;
89 sk_sp<SkImageFilter> background(SkImageFilters::Image(fCheckerboard,
91 for (size_t i = 0; i < std::size(gModes); i++) {
92 paint.setImageFilter(SkImageFilters::Blend(gModes[i], background));
93 DrawClippedBitmap(canvas, fBitmap, paint, x, y);
94 x += fBitmap.width() + MARGIN;
95 if (x + fBitmap.width() > WIDTH) {
96 x = 0;
97 y += fBitmap.height() + MARGIN;
98 }
99 }
100 // Test arithmetic mode as image filter
101 paint.setImageFilter(SkImageFilters::Arithmetic(0, 1, 1, 0, true, background, nullptr));
102 DrawClippedBitmap(canvas, fBitmap, paint, x, y);
103 x += fBitmap.width() + MARGIN;
104 if (x + fBitmap.width() > WIDTH) {
105 x = 0;
106 y += fBitmap.height() + MARGIN;
107 }
108 // Test nullptr mode
109 paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kSrcOver, background));
110 DrawClippedBitmap(canvas, fBitmap, paint, x, y);
111 x += fBitmap.width() + MARGIN;
112 if (x + fBitmap.width() > WIDTH) {
113 x = 0;
114 y += fBitmap.height() + MARGIN;
115 }
117 SkIntToScalar(fBitmap.height() + 4));
118 // Test offsets on SrcMode (uses fixed-function blend)
119 sk_sp<SkImage> bitmapImage(fBitmap.asImage());
120 sk_sp<SkImageFilter> foreground(SkImageFilters::Image(std::move(bitmapImage),
122 sk_sp<SkImageFilter> offsetForeground(SkImageFilters::Offset(4, -4, foreground));
123 sk_sp<SkImageFilter> offsetBackground(SkImageFilters::Offset(4, 4, background));
124 paint.setImageFilter(SkImageFilters::Blend(
125 SkBlendMode::kSrcOver, offsetBackground, offsetForeground));
126 DrawClippedPaint(canvas, clipRect, paint, x, y);
127 x += fBitmap.width() + MARGIN;
128 if (x + fBitmap.width() > WIDTH) {
129 x = 0;
130 y += fBitmap.height() + MARGIN;
131 }
132 // Test offsets on Darken (uses shader blend)
133 paint.setImageFilter(SkImageFilters::Blend(
134 SkBlendMode::kDarken, offsetBackground, offsetForeground));
135 DrawClippedPaint(canvas, clipRect, paint, x, y);
136 x += fBitmap.width() + MARGIN;
137 if (x + fBitmap.width() > WIDTH) {
138 x = 0;
139 y += fBitmap.height() + MARGIN;
140 }
141 // Test cropping
142 constexpr size_t nbSamples = 3;
143 const SkBlendMode sampledModes[nbSamples] = {
145 };
146 int offsets[nbSamples][4] = {{ 10, 10, -16, -16},
147 { 10, 10, 10, 10},
148 {-10, -10, -6, -6}};
149 for (size_t i = 0; i < nbSamples; ++i) {
150 SkIRect cropRect = SkIRect::MakeXYWH(offsets[i][0],
151 offsets[i][1],
152 fBitmap.width() + offsets[i][2],
153 fBitmap.height() + offsets[i][3]);
154 paint.setImageFilter(SkImageFilters::Blend(sampledModes[i], offsetBackground,
155 offsetForeground, &cropRect));
156 DrawClippedPaint(canvas, clipRect, paint, x, y);
157 x += fBitmap.width() + MARGIN;
158 if (x + fBitmap.width() > WIDTH) {
159 x = 0;
160 y += fBitmap.height() + MARGIN;
161 }
162 }
163 // Test small bg, large fg with Screen (uses shader blend)
164 SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 60, 60);
165 sk_sp<SkImageFilter> cropped(SkImageFilters::Offset(0, 0, foreground, &cropRect));
166 paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kScreen, cropped, background));
167 DrawClippedPaint(canvas, clipRect, paint, x, y);
168 x += fBitmap.width() + MARGIN;
169 if (x + fBitmap.width() > WIDTH) {
170 x = 0;
171 y += fBitmap.height() + MARGIN;
172 }
173 // Test small fg, large bg with Screen (uses shader blend)
174 paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kScreen, background, cropped));
175 DrawClippedPaint(canvas, clipRect, paint, x, y);
176 x += fBitmap.width() + MARGIN;
177 if (x + fBitmap.width() > WIDTH) {
178 x = 0;
179 y += fBitmap.height() + MARGIN;
180 }
181 // Test small fg, large bg with SrcIn with a crop that forces it to full size.
182 // This tests that SkXfermodeImageFilter correctly applies the compositing mode to
183 // the region outside the foreground.
184 SkIRect cropRectFull = SkIRect::MakeXYWH(0, 0, 80, 80);
185 paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kSrcIn, background, cropped,
186 &cropRectFull));
187 DrawClippedPaint(canvas, clipRect, paint, x, y);
188 x += fBitmap.width() + MARGIN;
189 if (x + fBitmap.width() > WIDTH) {
190 x = 0;
191 y += fBitmap.height() + MARGIN;
192 }
193 }
194
195private:
196 static void DrawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint,
197 int x, int y) {
198 canvas->save();
200 canvas->clipIRect(bitmap.bounds());
201 canvas->drawImage(bitmap.asImage(), 0, 0, SkSamplingOptions(), &paint);
202 canvas->restore();
203 }
204
205 static void DrawClippedPaint(SkCanvas* canvas, const SkRect& rect, const SkPaint& paint,
206 int x, int y) {
207 canvas->save();
209 canvas->clipRect(rect);
210 canvas->drawPaint(paint);
211 canvas->restore();
212 }
213
214 SkBitmap fBitmap;
215 sk_sp<SkImage> fCheckerboard;
216
217 using INHERITED = GM;
218};
219
220//////////////////////////////////////////////////////////////////////////////
221
223
224} // namespace skiagm
SkBlendMode
Definition: SkBlendMode.h:38
@ kSrcOut
r = s * (1-da)
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kPlus
r = min(s + d, 1)
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kDstIn
r = d * sa
@ kModulate
r = s*d
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kScreen
r = s + d - s*d
@ kSrcOver
r = s + (1-sa)*d
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDstOut
r = d * (1-sa)
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
@ kSrcIn
r = s * da
@ kClear
r = 0
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
#define SkIntToScalar(x)
Definition: SkScalar.h:57
constexpr SkBlendMode gModes[]
Definition: aarectmodes.cpp:73
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
int width() const
Definition: SkBitmap.h:149
int height() const
Definition: SkBitmap.h:158
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void clipIRect(const SkIRect &irect, SkClipOp op=SkClipOp::kIntersect)
Definition: SkCanvas.h:991
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void clear(SkColor color)
Definition: SkCanvas.h:1199
int save()
Definition: SkCanvas.cpp:447
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
static sk_sp< SkImageFilter > Arithmetic(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool enforcePMColor, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Image(sk_sp< SkImage > image, const SkRect &srcRect, const SkRect &dstRect, const SkSamplingOptions &sampling)
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Offset(SkScalar dx, SkScalar dy, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
void setBGColor(SkColor)
Definition: gm.cpp:159
void onDraw(SkCanvas *canvas) override
SkString getName() const override
const Paint & paint
Definition: color_source.cc:38
double y
double x
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SkBitmap CreateStringBitmap(int w, int h, SkColor c, int x, int y, int textSize, const char *str)
sk_sp< SkImage > create_checkerboard_image(int w, int h, SkColor c1, SkColor c2, int checkSize)
Definition: ToolUtils.cpp:168
Definition: bitmap.py:1
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
list offsets
Definition: mskp_parser.py:37
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
Definition: SkRect.h:32
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
#define WIDTH
#define MARGIN
#define HEIGHT