Flutter Engine
The Flutter Engine
StrokeTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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/SkRect.h"
16#include "src/core/SkPathPriv.h"
17#include "tests/Test.h"
18
19#include <array>
20#include <cstddef>
21#include <cstdint>
22
23static bool equal(const SkRect& a, const SkRect& b) {
24 return SkScalarNearlyEqual(a.left(), b.left()) &&
25 SkScalarNearlyEqual(a.top(), b.top()) &&
26 SkScalarNearlyEqual(a.right(), b.right()) &&
27 SkScalarNearlyEqual(a.bottom(), b.bottom());
28}
29
31 uint32_t hexCubicVals[] = {
32 0x424c1086, 0x44bcf0cb, // fX=51.0161362 fY=1511.52478
33 0x424c107c, 0x44bcf0cb, // fX=51.0160980 fY=1511.52478
34 0x424c10c2, 0x44bcf0cb, // fX=51.0163651 fY=1511.52478
35 0x424c1119, 0x44bcf0ca, // fX=51.0166969 fY=1511.52466
36 };
37 SkPoint cubicVals[] = {
38 {51.0161362f, 1511.52478f },
39 {51.0160980f, 1511.52478f },
40 {51.0163651f, 1511.52478f },
41 {51.0166969f, 1511.52466f },
42 };
44
46 paint.setStrokeWidth(0.394537568f);
47 SkPath path, fillPath;
48 path.moveTo(cubicVals[0]);
49 path.cubicTo(cubicVals[1], cubicVals[2], cubicVals[3]);
51 path.reset();
52 path.moveTo(SkBits2Float(hexCubicVals[0]), SkBits2Float(hexCubicVals[1]));
53 path.cubicTo(SkBits2Float(hexCubicVals[2]), SkBits2Float(hexCubicVals[3]),
54 SkBits2Float(hexCubicVals[4]), SkBits2Float(hexCubicVals[5]),
55 SkBits2Float(hexCubicVals[6]), SkBits2Float(hexCubicVals[7]));
57}
58
60 const SkScalar width = SkIntToScalar(10);
62
64 paint.setStrokeWidth(width);
65
66 SkRect r = { 0, 0, SkIntToScalar(200), SkIntToScalar(100) };
67
68 SkRect outer(r);
69 outer.outset(width/2, width/2);
70
71 static const SkPaint::Join joins[] = {
73 };
74
75 for (size_t i = 0; i < std::size(joins); ++i) {
76 paint.setStrokeJoin(joins[i]);
77
78 SkPath path, fillPath;
79 path.addRect(r);
81
82 REPORTER_ASSERT(reporter, equal(outer, fillPath.getBounds()));
83
84 bool isMiter = SkPaint::kMiter_Join == joins[i];
85 SkRect nested[2];
86 REPORTER_ASSERT(reporter, SkPathPriv::IsNestedFillRects(fillPath, nested) == isMiter);
87 if (isMiter) {
88 SkRect inner(r);
89 inner.inset(width/2, width/2);
90 REPORTER_ASSERT(reporter, equal(nested[0], outer));
91 REPORTER_ASSERT(reporter, equal(nested[1], inner));
92 }
93 }
94}
95
97 {
101
102 // Test that style mismatch is detected.
103 s2.setHairlineStyle();
105
106 s1.setHairlineStyle();
108
109 // ResScale is not part of equality.
110 s1.setResScale(2.1f);
111 s2.setResScale(1.2f);
113 s1.setFillStyle();
114 s2.setFillStyle();
116 s1.setStrokeStyle(1.0f, false);
117 s2.setStrokeStyle(1.0f, false);
121 }
122
123 // Stroke parameters on fill or hairline style are not part of equality.
124 {
127 for (int i = 0; i < 2; ++i) {
135 s1.setHairlineStyle();
136 s2.setHairlineStyle();
137 }
138 }
139
140 // Stroke parameters on stroke style are part of equality.
141 {
146 s1.setStrokeStyle(1.0f, false);
147
148 s2.setStrokeStyle(1.0f, true);
150
151 s2.setStrokeStyle(2.1f, false);
153
154 s2.setStrokeStyle(1.0f, false);
156
158 REPORTER_ASSERT(reporter, s1.hasEqualEffect(s2)); // Miter limit not relevant to butt caps.
163
164 // Sets fill.
165 s1.setStrokeStyle(0.0f, true);
166 s2.setStrokeStyle(0.0f, true);
168 }
169}
170
171// From skbug.com/6491. The large stroke width can cause numerical instabilities.
175 paint.setStrokeWidth(1.49679073e+10f);
176
177 SkPath path;
178 path.moveTo(SkBits2Float(0x46380000), SkBits2Float(0xc6380000)); // 11776, -11776
179 path.lineTo(SkBits2Float(0x46a00000), SkBits2Float(0xc6a00000)); // 20480, -20480
180 path.lineTo(SkBits2Float(0x468c0000), SkBits2Float(0xc68c0000)); // 17920, -17920
181 path.lineTo(SkBits2Float(0x46100000), SkBits2Float(0xc6100000)); // 9216, -9216
182 path.lineTo(SkBits2Float(0x46380000), SkBits2Float(0xc6380000)); // 11776, -11776
183 path.close();
184
185 SkPath strokeAndFillPath;
186 skpathutils::FillPathWithPaint(path, paint, &strokeAndFillPath);
187}
188
194}
reporter
Definition: FontMgrTest.cpp:39
static float SkBits2Float(uint32_t bits)
Definition: SkFloatBits.h:48
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
#define SkIntToScalar(x)
Definition: SkScalar.h:57
static void test_strokerect(skiatest::Reporter *reporter)
Definition: StrokeTest.cpp:59
static void test_strokecubic(skiatest::Reporter *reporter)
Definition: StrokeTest.cpp:30
DEF_TEST(Stroke, reporter)
Definition: StrokeTest.cpp:189
static void test_big_stroke(skiatest::Reporter *reporter)
Definition: StrokeTest.cpp:172
static void test_strokerec_equality(skiatest::Reporter *reporter)
Definition: StrokeTest.cpp:96
static bool equal(const SkRect &a, const SkRect &b)
Definition: StrokeTest.cpp:23
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
@ kRound_Cap
adds circle
Definition: SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition: SkPaint.h:334
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition: SkPaint.h:195
@ kRound_Join
adds circle
Definition: SkPaint.h:360
@ kMiter_Join
extends to miter limit
Definition: SkPaint.h:359
@ kBevel_Join
connects outside edges
Definition: SkPaint.h:361
static bool IsNestedFillRects(const SkPath &, SkRect rect[2], SkPathDirection dirs[2]=nullptr)
Definition: SkPath.cpp:3780
Definition: SkPath.h:59
const SkRect & getBounds() const
Definition: SkPath.cpp:430
void setHairlineStyle()
Definition: SkStrokeRec.cpp:86
void setStrokeStyle(SkScalar width, bool strokeAndFill=false)
Definition: SkStrokeRec.cpp:91
void setFillStyle()
Definition: SkStrokeRec.cpp:81
bool hasEqualEffect(const SkStrokeRec &other) const
Definition: SkStrokeRec.h:130
void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit)
Definition: SkStrokeRec.h:65
void setResScale(SkScalar rs)
Definition: SkStrokeRec.h:75
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
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
int32_t width
void inset(float dx, float dy)
Definition: SkRect.h:1060
void outset(float dx, float dy)
Definition: SkRect.h:1077