Flutter Engine
The Flutter Engine
DashPathEffectTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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
12#include "include/core/SkPath.h"
16#include "include/core/SkRect.h"
24#include "tests/Test.h"
25
26#include <array>
27
28// crbug.com/348821 was rooted in SkDashPathEffect refusing to flatten and unflatten itself when
29// the effect is nonsense. Here we test that it fails when passed nonsense parameters.
30
31DEF_TEST(DashPathEffectTest_crbug_348821, r) {
32 SkScalar intervals[] = { 1.76934361e+36f, 2.80259693e-45f }; // Values from bug.
33 const int count = 2;
34 SkScalar phase = SK_ScalarInfinity; // Used to force a nonsense effect.
35 sk_sp<SkPathEffect> dash(SkDashPathEffect::Make(intervals, count, phase));
36
37 REPORTER_ASSERT(r, dash == nullptr);
38}
39
40// Test out the asPoint culling behavior.
41DEF_TEST(DashPathEffectTest_asPoints, r) {
42
43 const SkScalar intervals[] = { 1.0f, 1.0f };
44 const int count = 2;
45 sk_sp<SkPathEffect> dash(SkDashPathEffect::Make(intervals, count, 0.0f));
46
47 SkRect cull = SkRect::MakeWH(1.0f, 1.0f);
48
49 const struct {
50 SkPoint fPts[2];
51 bool fExpectedResult;
52 } testCases[] = {
53 { { { -5.0f, 0.5f }, { -4.0f, 0.5f } }, false }, // off to the left
54 { { { 4.0f, 0.5f }, { 5.0f, 0.5f } }, false }, // off to the right
55 { { { 0.5f, 4.0f }, { 0.5f, 5.0f } }, false }, // off the bottom
56 { { { 0.5f, -5.0f }, { 0.5f, -4.0f } }, false }, // off the top
57 { { { 0.5f, 0.2f }, { 0.5f, 0.8f } }, true }, // entirely inside vertical
58 { { { 0.2f, 0.5f }, { 0.8f, 0.5f } }, true }, // entirely inside horizontal
59 { { { 0.5f, -5.0f }, { 0.5f, 5.0f } }, true }, // straddles both sides vertically
60 { { { -5.0f, 0.5f }, { 5.0f, 0.5f } }, true }, // straddles both sides horizontally
61 { { { 0.5f, -5.0f }, { 0.5f, 0.5f } }, true }, // straddles top
62 { { { 0.5f, 5.0f }, { 0.5f, 0.5f } }, true }, // straddles bottom
63 { { { -5.0f, 0.5f }, { 0.5f, 0.5f } }, true }, // straddles left
64 { { { 5.0f, 0.5f }, { 0.5f, 0.5f } }, true }, // straddles right
65 { { { 0.5f, 0.5f }, { 0.5f, 0.5f } }, false }, // zero length
66 };
67
70 paint.setStrokeWidth(1.0f);
71 SkStrokeRec rec(paint);
72
73 static const int kNumMats = 3;
74 SkMatrix mats[kNumMats];
75 mats[0].reset();
76 mats[1].setRotate(90, 0.5f, 0.5f);
77 mats[2].setTranslate(10.0f, 10.0f);
78
79 for (int i = 0; i < kNumMats; ++i) {
80 for (int j = 0; j < (int)std::size(testCases); ++j) {
81 for (int k = 0; k < 2; ++k) { // exercise alternating endpoints
83 SkPath src;
84
85 src.moveTo(testCases[j].fPts[k]);
86 src.lineTo(testCases[j].fPts[(k+1)%2]);
87
88 bool actualResult = as_PEB(dash)->asPoints(&results, src, rec, mats[i], &cull);
89 if (i < 2) {
90 REPORTER_ASSERT(r, actualResult == testCases[j].fExpectedResult);
91 } else {
92 // On the third pass all the lines should be outside the translated cull rect
93 REPORTER_ASSERT(r, !actualResult);
94 }
95 }
96 }
97 }
98}
99
100DEF_TEST(DashPath_bug4871, r) {
101 SkPath path;
102 path.moveTo(30, 24);
103 path.cubicTo(30.002f, 24, 30, 24, 30, 24);
104 path.close();
105
106 SkScalar intervals[2] = { 1, 1 };
107 sk_sp<SkPathEffect> dash(SkDashPathEffect::Make(intervals, 2, 0));
108
111 paint.setPathEffect(dash);
112
113 SkPath fill;
115}
116
117// Verify that long lines with many dashes don't cause overflows/OOMs.
118DEF_TEST(DashPathEffectTest_asPoints_limit, r) {
120 SkCanvas* canvas = surface->getCanvas();
121
122 SkPaint p;
123 p.setStyle(SkPaint::kStroke_Style);
124 // force the bounds to outset by a large amount
125 p.setStrokeWidth(5.0e10f);
126 const SkScalar intervals[] = { 1, 1 };
127 p.setPathEffect(SkDashPathEffect::Make(intervals, std::size(intervals), 0));
128 canvas->drawLine(1, 1, 1, 5.0e10f, p);
129}
130
131// This used to cause SkDashImpl to walk off the end of the intervals array, due to underflow
132// trying to substract a smal value from a large one in floats.
133DEF_TEST(DashCrazy_crbug_875494, r) {
134 SkScalar vals[] = { 98, 94, 2888458849.f, 227, 0, 197 };
135 const int N = std::size(vals);
136
137 SkRect cull = SkRect::MakeXYWH(43,236,57,149);
138 SkPath path;
139 path.addRect(cull);
140
144 paint.setPathEffect(SkDashPathEffect::Make(vals, N, 222));
146}
147
SkPoint fPts[2]
DEF_TEST(DashPathEffectTest_crbug_348821, r)
int count
Definition: FontMgrTest.cpp:50
static SkPath path2()
static SkPathEffectBase * as_PEB(SkPathEffect *effect)
#define SK_ScalarInfinity
Definition: SkScalar.h:26
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define N
Definition: beziers.cpp:19
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:254
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:452
SkMatrix & reset()
Definition: SkMatrix.cpp:49
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
bool asPoints(PointData *results, const SkPath &src, const SkStrokeRec &, const SkMatrix &, const SkRect *cullR) const
Definition: SkPath.h:59
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
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
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
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23
static SkImageInfo MakeN32Premul(int width, int height)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609