15#include "gtest/gtest.h"
31 const std::vector<std::unique_ptr<DlImage>>&
images) {
32 canvas->
Scale(0.2, 0.2);
41 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
45 auto draw = [](
DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>&
images) {
54 std::vector<sk_sp<DlImage>>
images;
55 images.emplace_back(CreateDlImageForFixture(
"kalimba.jpg"));
58 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
64 Point content_scale = GetContentScale();
65 auto draw = [content_scale](
DlCanvas* canvas,
66 const std::vector<sk_sp<DlImage>>&
images) {
67 canvas->
Scale(content_scale.
x, content_scale.
y);
92 canvas->
SaveLayer(save_layer_bounds,
nullptr, backdrop.get());
108 std::vector<sk_sp<DlImage>>
images;
111 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
119 canvas->SaveLayer(rect.
Expand(8.0f), &layer_paint);
126 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
132 builder.
Scale(1.3f, 1.3f);
135 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
139void DrawBlurGrid(
DlCanvas* canvas) {
145 std::vector<Scalar> blur_radii = {10, 30, 50};
146 for (
size_t i = 0;
i < blur_radii.size(); ++
i) {
148 auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
151 Scalar yval = gap +
i * (gap +
height);
166 Point content_scale = GetContentScale();
167 auto draw = [content_scale](
DlCanvas* canvas,
168 const std::vector<sk_sp<DlImage>>&
images) {
169 canvas->
Scale(content_scale.
x, content_scale.
y);
171 DrawBlurGrid(canvas);
175 std::vector<sk_sp<DlImage>>
images;
178 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
182 Point content_scale = GetContentScale();
183 auto draw = [content_scale](
DlCanvas* canvas,
184 const std::vector<sk_sp<DlImage>>&
images) {
185 canvas->
Scale(content_scale.
x, content_scale.
y);
187 canvas->
Scale(0.33, 0.33);
188 DrawBlurGrid(canvas);
192 std::vector<sk_sp<DlImage>>
images;
195 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
199 Point content_scale = GetContentScale();
200 auto draw = [content_scale](
DlCanvas* canvas,
201 const std::vector<sk_sp<DlImage>>&
images) {
202 canvas->
Scale(content_scale.
x, content_scale.
y);
205 canvas->
Scale(0.33, 0.33);
209 DrawBlurGrid(canvas);
213 std::vector<sk_sp<DlImage>>
images;
216 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
221 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
224 auto blur_sigmas = std::array{5.0f, 10.0f, 20.0f};
225 auto blur_colors = std::array{
239 path_builder.
MoveTo(corner + relative_from);
241 path_builder.
LineTo(corner + relative_from);
249 path_builder.
CubicCurveTo(corner + relative_from * magic,
250 corner + relative_to * magic,
251 corner + relative_to);
266 for (
size_t i = 0;
i < blur_sigmas.size();
i++) {
274 rect = rect.
Shift(150.0f, 0.0f);
275 builder.
DrawPath(make_rrect_path(rect, 10.0f, 10.0f), paint);
276 rect = rect.
Shift(-150.0f, 0.0f);
278 rect = rect.
Shift(0.0f, 200.0f);
280 rect = rect.
Shift(150.0f, 0.0f);
281 builder.
DrawPath(make_rrect_path(rect, 10.0f, 20.0f), paint);
282 rect = rect.
Shift(-150.0f, 0.0f);
284 rect = rect.
Shift(0.0f, 200.0f);
286 rect = rect.
Shift(150.0f, 0.0f);
287 builder.
DrawPath(make_rrect_path(rect, 20.0f, 10.0f), paint);
288 rect = rect.
Shift(-150.0f, 0.0f);
291 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
295 Point content_scale = GetContentScale();
296 auto draw = [content_scale](
DlCanvas* canvas,
297 const std::vector<sk_sp<DlImage>>&
images) {
298 canvas->
Scale(content_scale.
x, content_scale.
y);
318 for (
int degrees = 0; degrees < 360; degrees += 30) {
320 canvas->
DrawDashedLine(center + inner * delta, center + outer * delta,
321 dash_on, dash_off, thick_paint);
322 canvas->
DrawDashedLine(center + inner * delta, center + outer * delta,
323 dash_on, dash_off, middle_paint);
324 canvas->
DrawDashedLine(center + inner * delta, center + outer * delta,
325 dash_on, dash_off, thin_paint);
348 std::vector<sk_sp<DlImage>>
images;
351 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
361 builder.
SaveLayer(std::nullopt, &save_paint);
376 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
381 const uint32_t* ptr =
reinterpret_cast<const uint32_t*
>(img->
GetBytes());
384 for (uint32_t j = 0; j < img->
GetWidth(); ++j) {
385 uint32_t pixel = *ptr++;
386 if ((pixel & 0x00ffffff) != 0) {
387 max_y = std::max(max_y,
static_cast<int32_t
>(
i));
395 const uint32_t* ptr =
reinterpret_cast<const uint32_t*
>(img->
GetBytes());
397 std::vector<size_t> boundaries;
398 uint32_t
value = *ptr++;
400 if (((*ptr & 0x00ffffff) != 0) != ((value & 0x00ffffff) != 0)) {
401 boundaries.push_back(
i);
406 assert(boundaries.size() == 6);
407 return boundaries[4] - boundaries[3];
420 builder.
Scale(scale, scale);
426 return builder.
Build();
429 std::unique_ptr<impeller::testing::Screenshot> right =
430 MakeScreenshot(
callback(
"h", 0.444));
432 GTEST_SKIP() <<
"making screenshots not supported.";
434 std::unique_ptr<impeller::testing::Screenshot> left =
435 MakeScreenshot(
callback(
"e", 0.444));
437 int32_t left_max_y = CalculateMaxY(left.get());
438 int32_t right_max_y = CalculateMaxY(right.get());
439 int32_t y_diff = std::abs(left_max_y - right_max_y);
440 EXPECT_TRUE(y_diff <= 2) <<
"y diff: " << y_diff;
452 builder.
Scale(scale, scale);
458 return builder.
Build();
461 std::optional<int32_t> last_space;
462 for (
int i = 0;
i <= 100; ++
i) {
463 Scalar scale = 0.440 +
i / 1000.0;
464 std::unique_ptr<impeller::testing::Screenshot> right =
465 MakeScreenshot(
callback(
"ui", scale));
467 GTEST_SKIP() <<
"making screenshots not supported.";
470 int32_t space = CalculateSpaceBetweenUI(right.get());
471 if (last_space.has_value()) {
472 int32_t diff = abs(space - *last_space);
473 EXPECT_TRUE(diff <= 1)
474 <<
"i:" <<
i <<
" space:" << space <<
" last_space:" << *last_space;
481struct LeftmostIntensity {
488LeftmostIntensity CalculateLeftmostIntensity(
490 LeftmostIntensity result = {.x =
static_cast<int32_t
>(img->
GetWidth()),
492 const uint32_t* ptr =
reinterpret_cast<const uint32_t*
>(img->
GetBytes());
494 for (int32_t j = 0; j < static_cast<int32_t>(img->
GetWidth()); ++j) {
495 if (((*ptr & 0x00ffffff) != 0)) {
498 result.value = (*ptr & 0xff00) >> 8;
499 }
else if (j == result.x) {
501 std::max(
static_cast<int32_t
>(*ptr & 0xff), result.value);
527 return builder.
Build();
530 LeftmostIntensity intensity[5];
531 for (
int i = 0;
i <= 4; ++
i) {
532 Scalar offset = 10 + (
i / 4.0);
533 std::unique_ptr<impeller::testing::Screenshot> right =
536 GTEST_SKIP() <<
"making screenshots not supported.";
538 intensity[
i] = CalculateLeftmostIntensity(right.get());
539 ASSERT_NE(intensity[
i].
value, 0);
541 for (
int i = 1;
i < 5; ++
i) {
542 EXPECT_TRUE(intensity[
i].
x - intensity[
i - 1].
x == 1 ||
546 EXPECT_EQ(intensity[4].
x - intensity[0].
x, 1);
557 builder.
Scale(scalar, scalar);
567 return builder.
Build();
570 LeftmostIntensity intensity[5];
571 Scalar offset_fraction = 0.25 / scalar;
572 for (
int i = 0;
i <= 4; ++
i) {
573 Scalar offset = 10 + (offset_fraction *
i);
574 std::unique_ptr<impeller::testing::Screenshot> right =
577 GTEST_SKIP() <<
"making screenshots not supported.";
579 intensity[
i] = CalculateLeftmostIntensity(right.get());
580 ASSERT_NE(intensity[
i].
value, 0);
582 for (
int i = 1;
i < 5; ++
i) {
583 EXPECT_TRUE(intensity[
i].
x - intensity[
i - 1].
x == 1 ||
587 EXPECT_EQ(intensity[4].
x - intensity[0].
x, 1);
598 builder.
Scale(scalar, scalar);
609 return builder.
Build();
612 LeftmostIntensity intensity[5];
613 Scalar offset_fraction = 0.25 / scalar;
614 for (
int i = 0;
i <= 4; ++
i) {
615 Scalar offset = 10 + (offset_fraction *
i);
616 std::unique_ptr<impeller::testing::Screenshot> right =
619 GTEST_SKIP() <<
"making screenshots not supported.";
621 intensity[
i] = CalculateLeftmostIntensity(right.get());
622 ASSERT_NE(intensity[
i].
value, 0);
624 for (
int i = 1;
i < 5; ++
i) {
625 EXPECT_TRUE(intensity[
i].
x - intensity[
i - 1].
x == 1 ||
629 EXPECT_EQ(intensity[4].
x - intensity[0].
x, 1);
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
void DrawColor(DlColor color, DlBlendMode mode) override
void DrawCircle(const DlPoint ¢er, DlScalar radius, const DlPaint &paint) override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void Scale(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void DrawPaint(const DlPaint &paint) override
sk_sp< DisplayList > Build()
void DrawPath(const DlPath &path, const DlPaint &paint) override
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
Developer-facing API for rendering anything within the engine.
virtual void DrawPaint(const DlPaint &paint)=0
virtual void DrawCircle(const DlPoint ¢er, DlScalar radius, const DlPaint &paint)=0
virtual void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint)=0
virtual void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt)=0
virtual void DrawRect(const DlRect &rect, const DlPaint &paint)=0
virtual void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr)=0
virtual void Translate(DlScalar tx, DlScalar ty)=0
virtual void DrawColor(DlColor color, DlBlendMode mode=DlBlendMode::kSrcOver)=0
virtual void Rotate(DlScalar degrees)=0
virtual void DrawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length, const DlPaint &paint)=0
virtual void ClipPath(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)=0
virtual void Scale(DlScalar sx, DlScalar sy)=0
static std::shared_ptr< DlImageFilter > MakeDilate(DlScalar radius_x, DlScalar radius_y)
static std::shared_ptr< DlImageFilter > MakeMatrix(const DlMatrix &matrix, DlImageSampling sampling)
DlPaint & setColor(DlColor color)
DlPaint & setAntiAlias(bool isAntiAlias)
DlPaint & setStrokeCap(DlStrokeCap cap)
DlPaint & setStrokeWidth(float width)
DlPaint & setAlpha(uint8_t alpha)
DlPaint & setImageFilter(std::nullptr_t filter)
DlPaint & setMaskFilter(std::nullptr_t filter)
DlPaint & setDrawStyle(DlDrawStyle style)
DlPathBuilder & LineTo(DlPoint p2)
Draw a line from the current point to the indicated point p2.
static constexpr const DlScalar kArcApproximationMagic
DlPathBuilder & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
DlPathBuilder & CubicCurveTo(DlPoint cp1, DlPoint cp2, DlPoint p2)
Draw a cubic bezier curve from the current point to the indicated point p2, using the indicated point...
virtual const uint8_t * GetBytes() const =0
Access raw data of the screenshot.
virtual size_t GetHeight() const =0
Returns the height of the image in pixels.
virtual size_t GetWidth() const =0
Returns the width of the image in pixels.
FlutterDesktopBinaryReply callback
#define FML_CHECK(condition)
Vector2 blur_radius
Blur radius in source pixels based on scaled_sigma.
std::array< MockImage, 3 > images
bool RenderTextInCanvasSkia(DlCanvas *canvas, const std::string &text, const std::string_view &font_fixture, DlPoint position, const TextRenderOptions &options)
TEST_P(DlGoldenTest, TextBlurMaskFilterRespectCTM)
impeller::Scalar DlScalar
@ kButt
no stroke extension
@ kStroke
strokes boundary of shapes
@ kNormal
fuzzy inside and outside
impeller::Vector2 DlVector2
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
static constexpr DlColor kMagenta()
static constexpr DlColor kWhite()
static constexpr DlColor kBlue()
static constexpr DlColor kBlack()
static constexpr DlColor kMaroon()
static constexpr DlColor ARGB(DlScalar a, DlScalar r, DlScalar g, DlScalar b)
Construct a 32 bit color from floating point A, R, G, and B color channels.
static constexpr DlColor kAqua()
static constexpr DlColor kYellow()
static constexpr DlColor kRed()
static constexpr DlColor kGreen()
static constexpr DlColor kCyan()
static constexpr Matrix MakeRow(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static RoundRect MakeRectRadius(const Rect &rect, Scalar radius)
static RoundRect MakeNinePatch(const Rect &rect, Scalar left, Scalar top, Scalar right, Scalar bottom)
static RoundRect MakeOval(const Rect &rect)
static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
static constexpr TPoint< Type > MakeXY(Type x, Type y)
constexpr TPoint< T > GetLeftTop() const
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr TPoint< T > GetRightBottom() const
constexpr TPoint< T > GetLeftBottom() const
constexpr TPoint< T > GetRightTop() const
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)