Flutter Engine
The Flutter Engine
Classes | Namespaces | Functions | Variables
complexclip.cpp File Reference
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "tools/DecodeUtils.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"
#include <string.h>

Go to the source code of this file.

Classes

class  skiagm::ComplexClipGM
 

Namespaces

namespace  skiagm
 

Functions

 DEF_SIMPLE_GM (clip_shader, canvas, 840, 650)
 
 DEF_SIMPLE_GM (clip_shader_layer, canvas, 430, 320)
 
 DEF_SIMPLE_GM (clip_shader_nested, canvas, 256, 256)
 
 DEF_SIMPLE_GM (clip_shader_persp, canvas, 1370, 1030)
 
 DEF_SIMPLE_GM (clip_shader_difference, canvas, 512, 512)
 

Variables

constexpr SkColor skiagm::gPathColor = SK_ColorBLACK
 
constexpr SkColor skiagm::gClipAColor = SK_ColorBLUE
 
constexpr SkColor skiagm::gClipBColor = SK_ColorRED
 

Function Documentation

◆ DEF_SIMPLE_GM() [1/5]

DEF_SIMPLE_GM ( clip_shader  ,
canvas  ,
840  ,
650   
)

Definition at line 214 of file complexclip.cpp.

214 {
215 auto img = ToolUtils::GetResourceAsImage("images/yellow_rose.png");
216 auto sh = img->makeShader(SkSamplingOptions());
217
218 SkRect r = SkRect::MakeIWH(img->width(), img->height());
219 SkPaint p;
220
221 canvas->translate(10, 10);
222 canvas->drawImage(img, 0, 0);
223
224 canvas->save();
225 canvas->translate(img->width() + 10, 0);
226 canvas->clipShader(sh, SkClipOp::kIntersect);
227 p.setColor(SK_ColorRED);
228 canvas->drawRect(r, p);
229 canvas->restore();
230
231 canvas->save();
232 canvas->translate(0, img->height() + 10);
233 canvas->clipShader(sh, SkClipOp::kDifference);
234 p.setColor(SK_ColorGREEN);
235 canvas->drawRect(r, p);
236 canvas->restore();
237
238 canvas->save();
239 canvas->translate(img->width() + 10, img->height() + 10);
240 canvas->clipShader(sh, SkClipOp::kIntersect);
241 canvas->save();
242 SkMatrix lm = SkMatrix::Scale(1.0f/5, 1.0f/5);
243 canvas->clipShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
244 SkSamplingOptions(), lm));
245 canvas->drawImage(img, 0, 0);
246
247 canvas->restore();
248 canvas->restore();
249}
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: DecodeUtils.h:25
sh
Definition: run_sh.py:10
SkSamplingOptions(SkFilterMode::kLinear))
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623

◆ DEF_SIMPLE_GM() [2/5]

DEF_SIMPLE_GM ( clip_shader_difference  ,
canvas  ,
512  ,
512   
)

Definition at line 447 of file complexclip.cpp.

447 {
448 auto image = ToolUtils::GetResourceAsImage("images/yellow_rose.png");
449 canvas->clear(SK_ColorGRAY);
450
451 SkRect rect = SkRect::MakeWH(256, 256);
453 SkRect::MakeWH(64, 64));
456
458 paint.setColor(SK_ColorRED);
459 paint.setAntiAlias(true);
460
461 // TL: A rectangle
462 {
463 canvas->save();
464 canvas->translate(0, 0);
465 canvas->clipShader(shader, SkClipOp::kDifference);
466 canvas->drawRect(rect, paint);
467 canvas->restore();
468 }
469 // TR: A round rectangle
470 {
471 canvas->save();
472 canvas->translate(256, 0);
473 canvas->clipShader(shader, SkClipOp::kDifference);
474 canvas->drawRRect(SkRRect::MakeRectXY(rect, 64.f, 64.f), paint);
475 canvas->restore();
476 }
477 // BL: A path
478 {
479 canvas->save();
480 canvas->translate(0, 256);
481 canvas->clipShader(shader, SkClipOp::kDifference);
482
483 SkPath path;
484 path.moveTo(0.f, 128.f);
485 path.lineTo(128.f, 256.f);
486 path.lineTo(256.f, 128.f);
487 path.lineTo(128.f, 0.f);
488
489 SkScalar d = 64.f * SK_ScalarSqrt2;
490 path.moveTo(128.f - d, 128.f - d);
491 path.lineTo(128.f - d, 128.f + d);
492 path.lineTo(128.f + d, 128.f + d);
493 path.lineTo(128.f + d, 128.f - d);
494 canvas->drawPath(path, paint);
495 canvas->restore();
496 }
497 // BR: Text
498 {
499 canvas->save();
500 canvas->translate(256, 256);
501 canvas->clipShader(shader, SkClipOp::kDifference);
503 for (int y = 0; y < 4; ++y) {
504 canvas->drawString("Hello", 32.f, y * 64.f, font, paint);
505 }
506 canvas->restore();
507 }
508}
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
#define SK_ScalarSqrt2
Definition: SkScalar.h:20
Definition: SkFont.h:35
int width() const
Definition: SkImage.h:285
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:179
int height() const
Definition: SkImage.h:291
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition: SkMatrix.h:157
Definition: SkPath.h:59
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
const Paint & paint
Definition: color_source.cc:38
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
double y
sk_sp< const SkImage > image
Definition: SkRecords.h:269
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
sk_sp< SkTypeface > DefaultPortableTypeface()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
font
Font Metadata and Metrics.
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609

◆ DEF_SIMPLE_GM() [3/5]

DEF_SIMPLE_GM ( clip_shader_layer  ,
canvas  ,
430  ,
320   
)

Definition at line 251 of file complexclip.cpp.

251 {
252 auto img = ToolUtils::GetResourceAsImage("images/yellow_rose.png");
253 auto sh = img->makeShader(SkSamplingOptions());
254
255 SkRect r = SkRect::MakeIWH(img->width(), img->height());
256
257 canvas->translate(10, 10);
258 // now add the cool clip
259 canvas->clipRect(r);
260 canvas->clipShader(sh);
261 // now draw a layer with the same image, and watch it get restored w/ the clip
262 canvas->saveLayer(&r, nullptr);
263 canvas->drawColor(0xFFFF0000);
264 canvas->restore();
265}

◆ DEF_SIMPLE_GM() [4/5]

DEF_SIMPLE_GM ( clip_shader_nested  ,
canvas  ,
256  ,
256   
)

Definition at line 267 of file complexclip.cpp.

267 {
268 float w = 64.f;
269 float h = 64.f;
270
271 const SkColor gradColors[] = {SK_ColorBLACK, SkColorSetARGB(128, 128, 128, 128)};
272 auto s = SkGradientShader::MakeRadial({0.5f * w, 0.5f * h}, 0.1f * w, gradColors, nullptr,
273 2, SkTileMode::kRepeat, 0, nullptr);
274
275 SkPaint p;
276
277 // A large black rect affected by two gradient clips
278 canvas->save();
279 canvas->clipShader(s);
280 canvas->scale(2.f, 2.f);
281 canvas->clipShader(s);
282 canvas->drawRect(SkRect::MakeWH(w, h), p);
283 canvas->restore();
284
285 canvas->translate(0.f, 2.f * h);
286
287 // A small red rect, with no clipping
288 canvas->save();
289 p.setColor(SK_ColorRED);
290 canvas->drawRect(SkRect::MakeWH(w, h), p);
291 canvas->restore();
292}
uint32_t SkColor
Definition: SkColor.h:37
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
static sk_sp< SkShader > MakeRadial(const SkPoint &center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
struct MyStruct s
SkScalar w
SkScalar h

◆ DEF_SIMPLE_GM() [5/5]

DEF_SIMPLE_GM ( clip_shader_persp  ,
canvas  ,
1370  ,
1030   
)

Definition at line 351 of file complexclip.cpp.

351 {
352 // Each draw has a clipShader(image-shader), a clipShader(gradient-shader), a concat(persp-mat),
353 // and each shader may or may not be wrapped with a perspective local matrix.
354
355 // Pairs of configs that should match in appearance where first config doesn't use a local
356 // matrix (top row of GM) and the second does (bottom row of GM).
357 Config matches[][2] = {
358 // Everything has perspective
359 {{kConcatBeforeClips, kDoesntMatter, kNoLocalMat},
360 {kConcatAfterClips, kDoesntMatter, kBothWithLocalMat}},
361 // Image shader has perspective
362 {{kConcatBetweenClips, kClipGradientFirst, kNoLocalMat},
363 {kConcatAfterClips, kDoesntMatter, kImageWithLocalMat}},
364 // Gradient shader has perspective
365 {{kConcatBetweenClips, kClipImageFirst, kNoLocalMat},
366 {kConcatAfterClips, kDoesntMatter, kGradientWithLocalMat}}
367 };
368
369 // The image that is drawn
370 auto img = ToolUtils::GetResourceAsImage("images/yellow_rose.png");
371 // Scale factor always applied to the image shader so that it tiles
372 SkMatrix scale = SkMatrix::Scale(1.f / 4.f, 1.f / 4.f);
373 // The perspective matrix applied wherever needed
374 SkPoint src[4];
375 SkRect::Make(img->dimensions()).toQuad(src);
376 SkPoint dst[4] = {{0, 80.f},
377 {img->width() + 28.f, -100.f},
378 {img->width() - 28.f, img->height() + 100.f},
379 {0.f, img->height() - 80.f}};
380 SkMatrix persp;
382
383 SkMatrix perspScale = SkMatrix::Concat(persp, scale);
384
385 auto drawConfig = [&](Config config) {
386 canvas->save();
387
388 draw_banner(canvas, config);
389
390 // Make clipShaders (possibly with local matrices)
391 bool gradLM = config.fLM == kGradientWithLocalMat || config.fLM == kBothWithLocalMat;
392 const SkColor gradColors[] = {SK_ColorBLACK, SkColorSetARGB(128, 128, 128, 128)};
393 auto gradShader = SkGradientShader::MakeRadial({0.5f * img->width(), 0.5f * img->height()},
394 0.1f * img->width(), gradColors, nullptr, 2,
396 gradLM ? &persp : nullptr);
397 bool imageLM = config.fLM == kImageWithLocalMat || config.fLM == kBothWithLocalMat;
398 auto imgShader = img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
399 SkSamplingOptions(), imageLM ? perspScale : scale);
400
401 // Perspective before any clipShader
402 if (config.fConcat == kConcatBeforeClips) {
403 canvas->concat(persp);
404 }
405
406 // First clipshader
407 canvas->clipShader(config.fOrder == kClipImageFirst ? imgShader : gradShader);
408
409 // Perspective between clipShader
410 if (config.fConcat == kConcatBetweenClips) {
411 canvas->concat(persp);
412 }
413
414 // Second clipShader
415 canvas->clipShader(config.fOrder == kClipImageFirst ? gradShader : imgShader);
416
417 // Perspective after clipShader
418 if (config.fConcat == kConcatAfterClips) {
419 canvas->concat(persp);
420 }
421
422 // Actual draw and clip boundary are the same for all configs
423 canvas->clipIRect(img->bounds());
424 canvas->clear(SK_ColorBLACK);
425 canvas->drawImage(img, 0, 0);
426
427 canvas->restore();
428 };
429
430 SkIRect grid = persp.mapRect(SkRect::Make(img->dimensions())).roundOut();
431 grid.fLeft -= 20; // manual adjust to look nicer
432
433 canvas->translate(10.f, 10.f);
434
435 for (size_t i = 0; i < std::size(matches); ++i) {
436 canvas->save();
437 canvas->translate(-grid.fLeft, -grid.fTop);
438 drawConfig(matches[i][0]);
439 canvas->translate(0.f, grid.height());
440 drawConfig(matches[i][1]);
441 canvas->restore();
442
443 canvas->translate(grid.width(), 0.f);
444 }
445}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.h:1775
bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
Definition: SkMatrix.cpp:1385
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
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
def matches(file)
Definition: gen_manifest.py:38
dst
Definition: cp.py:12
const Scalar scale
Definition: SkRect.h:32
constexpr int32_t height() const
Definition: SkRect.h:165
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
void toQuad(SkPoint quad[4]) const
Definition: SkRect.cpp:50