Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Typedefs | Functions | Variables
TriangulatingPathRendererTests.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkArenaAlloc.h"
#include "src/base/SkFloatBits.h"
#include "src/base/SkRandom.h"
#include "src/core/SkPathPriv.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/ganesh/GrColorInfo.h"
#include "src/gpu/ganesh/GrEagerVertexAllocator.h"
#include "src/gpu/ganesh/GrFPArgs.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrFragmentProcessors.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrStyle.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/PathRenderer.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"
#include "src/gpu/ganesh/geometry/GrAATriangulator.h"
#include "src/gpu/ganesh/geometry/GrInnerFanTriangulator.h"
#include "src/gpu/ganesh/geometry/GrStyledShape.h"
#include "src/gpu/ganesh/geometry/GrTriangulator.h"
#include "src/gpu/ganesh/ops/TriangulatingPathRenderer.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
#include <cmath>
#include <cstddef>
#include <initializer_list>
#include <map>
#include <memory>
#include <utility>

Go to the source code of this file.

Classes

struct  Edge
 

Typedefs

using CreatePathFn = SkPath(*)()
 
using EdgeMap = std::map< Edge, int >
 

Functions

static bool operator< (const Edge &a, const Edge &b)
 
static void add_edge (EdgeMap &edgeMap, SkPoint p0, SkPoint p1)
 
static void add_tri_edges (skiatest::Reporter *r, EdgeMap &edgeMap, const SkPoint pts[3])
 
static EdgeMap simplify (const EdgeMap &edges, SkPathFillType fillType)
 
static void verify_simple_inner_polygons (skiatest::Reporter *r, const char *shapeName, SkPath path)
 
 DEF_TEST (GrInnerFanTriangulator, r)
 
static void test_crbug_1262444 (skiatest::Reporter *r)
 
 DEF_TEST (TriangulatorBugs, r)
 

Variables

CreatePathFn kNonEdgeAAPaths []
 

Typedef Documentation

◆ CreatePathFn

using CreatePathFn = SkPath(*)()

Definition at line 74 of file TriangulatingPathRendererTests.cpp.

◆ EdgeMap

using EdgeMap = std::map<Edge, int>

Definition at line 970 of file TriangulatingPathRendererTests.cpp.

Function Documentation

◆ add_edge()

static void add_edge ( EdgeMap edgeMap,
SkPoint  p0,
SkPoint  p1 
)
static

Definition at line 972 of file TriangulatingPathRendererTests.cpp.

972 {
973 Edge edge{p0, p1};
974 // First check if this edge already exists in reverse.
975 auto reverseIter = edgeMap.find(edge.reverse());
976 if (reverseIter != edgeMap.end()) {
977 --reverseIter->second;
978 } else {
979 ++edgeMap[edge];
980 }
981}

◆ add_tri_edges()

static void add_tri_edges ( skiatest::Reporter r,
EdgeMap edgeMap,
const SkPoint  pts[3] 
)
static

Definition at line 983 of file TriangulatingPathRendererTests.cpp.

983 {
984 for (int i = 0; i < 3; ++i) {
985 SkPoint p0=pts[i], p1=pts[(i+1)%3];
986 // The triangulator shouldn't output degenerate triangles.
987 REPORTER_ASSERT(r, p0 != p1);
988 add_edge(edgeMap, p0, p1);
989 }
990}
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
static void add_edge(EdgeMap &edgeMap, SkPoint p0, SkPoint p1)

◆ DEF_TEST() [1/2]

DEF_TEST ( GrInnerFanTriangulator  ,
 
)

Definition at line 1122 of file TriangulatingPathRendererTests.cpp.

1122 {
1123 verify_simple_inner_polygons(r, "simple triangle", SkPath().lineTo(1,0).lineTo(0,1));
1124 verify_simple_inner_polygons(r, "simple square", SkPath().lineTo(1,0).lineTo(1,1).lineTo(0,1));
1125 verify_simple_inner_polygons(r, "concave polygon", SkPath()
1126 .lineTo(1,0).lineTo(.5f,.5f).lineTo(1,1).lineTo(0,1));
1127 verify_simple_inner_polygons(r, "double wound triangle", SkPath()
1128 .lineTo(1,0).lineTo(0,1).lineTo(0,0).lineTo(1,0).lineTo(0,1));
1129 verify_simple_inner_polygons(r, "self-intersecting bowtie", SkPath()
1130 .lineTo(1,0).lineTo(0,1).lineTo(1,1));
1131 verify_simple_inner_polygons(r, "asymmetrical bowtie", SkPath()
1132 .lineTo(1,0).lineTo(0,1).lineTo(.1f,-.1f));
1133 verify_simple_inner_polygons(r, "bowtie with extremely small section", SkPath()
1134 .lineTo(1,0).lineTo(0,1).lineTo(1e-6f,-1e-6f));
1135 verify_simple_inner_polygons(r, "intersecting squares", SkPath()
1136 .lineTo(1,0).lineTo(1,1).lineTo(0,1)
1137 .moveTo(.5f,.5f).lineTo(1.5f,.5f).lineTo(1.5f,1.5f).lineTo(.5f,1.5f).close());
1138 verify_simple_inner_polygons(r, "6-point \"Star of David\"", SkPath()
1139 .moveTo(cosf(-SK_ScalarPI/3), sinf(-SK_ScalarPI/3))
1140 .lineTo(cosf(SK_ScalarPI/3), sinf(SK_ScalarPI/3))
1141 .lineTo(cosf(SK_ScalarPI), sinf(SK_ScalarPI))
1142 .moveTo(cosf(0), sinf(0))
1143 .lineTo(cosf(2*SK_ScalarPI/3), sinf(2*SK_ScalarPI/3))
1144 .lineTo(cosf(-2*SK_ScalarPI/3), sinf(-2*SK_ScalarPI/3)));
1145 verify_simple_inner_polygons(r, "double wound \"Star of David\"", SkPath()
1146 .moveTo(cosf(-SK_ScalarPI/3), sinf(-SK_ScalarPI/3))
1147 .lineTo(cosf(SK_ScalarPI/3), sinf(SK_ScalarPI/3))
1148 .lineTo(cosf(SK_ScalarPI), sinf(SK_ScalarPI))
1149 .lineTo(cosf(-SK_ScalarPI/3), sinf(-SK_ScalarPI/3))
1150 .lineTo(cosf(SK_ScalarPI/3), sinf(SK_ScalarPI/3))
1151 .lineTo(cosf(SK_ScalarPI), sinf(SK_ScalarPI))
1152 .moveTo(cosf(0), sinf(0))
1153 .lineTo(cosf(2*SK_ScalarPI/3), sinf(2*SK_ScalarPI/3))
1154 .lineTo(cosf(-2*SK_ScalarPI/3), sinf(-2*SK_ScalarPI/3)));
1156 verify_simple_inner_polygons(r, "\"pointy\" intersecting triangles", SkPath()
1157 .moveTo(0,-100).lineTo(-1e-6f,100).lineTo(1e-6f,100)
1158 .moveTo(-100,0).lineTo(100,1e-6f).lineTo(100,-1e-6f));
1159 verify_simple_inner_polygons(r, "overlapping rects with vertical collinear edges", SkPath()
1160 .moveTo(0,0).lineTo(0,2).lineTo(1,2).lineTo(1,0)
1161 .moveTo(0,1).lineTo(0,3).lineTo(1,3).lineTo(1,1));
1162 verify_simple_inner_polygons(r, "overlapping rects with horizontal collinear edges", SkPath()
1163 .lineTo(2,0).lineTo(2,1).lineTo(0,1)
1164 .moveTo(1,0).lineTo(3,0).lineTo(3,1).lineTo(1,1).close());
1165 for (int i = 0; i < (int)std::size(kNonEdgeAAPaths); ++i) {
1166 verify_simple_inner_polygons(r, SkStringPrintf("kNonEdgeAAPaths[%i]", i).c_str(),
1167 kNonEdgeAAPaths[i]());
1168 }
1169 SkRandom rand;
1170 for (int i = 0; i < 50; ++i) {
1171 auto randomPath = SkPath().moveTo(rand.nextF(), rand.nextF());
1172 for (int j = 0; j < i; ++j) {
1173 randomPath.lineTo(rand.nextF(), rand.nextF());
1174 }
1175 verify_simple_inner_polygons(r, SkStringPrintf("random_path_%i", i).c_str(), randomPath);
1176 }
1177}
#define SK_ScalarPI
Definition SkScalar.h:21
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
CreatePathFn kNonEdgeAAPaths[]
static void verify_simple_inner_polygons(skiatest::Reporter *r, const char *shapeName, SkPath path)
Type::kYUV Type::kRGBA() int(0.7 *637)
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPath & lineTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:718
float nextF()
Definition SkRandom.h:55
SkPath make_star(const SkRect &bounds, int numPts, int step)
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609

◆ DEF_TEST() [2/2]

DEF_TEST ( TriangulatorBugs  ,
 
)

Definition at line 1364 of file TriangulatingPathRendererTests.cpp.

1364 {
1366}
static void test_crbug_1262444(skiatest::Reporter *r)

◆ operator<()

static bool operator< ( const Edge a,
const Edge b 
)
static

Definition at line 954 of file TriangulatingPathRendererTests.cpp.

954 {
955 if (a.fP0.fX != b.fP0.fX) {
956 return a.fP0.fX < b.fP0.fX;
957 }
958 if (a.fP0.fY != b.fP0.fY) {
959 return a.fP0.fY < b.fP0.fY;
960 }
961 if (a.fP1.fX != b.fP1.fX) {
962 return a.fP1.fX < b.fP1.fX;
963 }
964 if (a.fP1.fY != b.fP1.fY) {
965 return a.fP1.fY < b.fP1.fY;
966 }
967 return false;
968}
static bool b
struct MyStruct a[10]

◆ simplify()

static EdgeMap simplify ( const EdgeMap edges,
SkPathFillType  fillType 
)
static

Definition at line 992 of file TriangulatingPathRendererTests.cpp.

992 {
993 // Prune out the edges whose count went to zero, and reverse the edges whose count is negative.
994 EdgeMap simplifiedEdges;
995 for (auto [edge, count] : edges) {
996 // We should only have one ordering of any given edge.
997 SkASSERT(edges.find(edge.reverse()) == edges.end());
998 if (fillType == SkPathFillType::kEvenOdd) {
999 count = abs(count) & 1;
1000 }
1001 if (count > 0) {
1002 simplifiedEdges[edge] = count;
1003 } else if (count < 0) {
1004 simplifiedEdges[edge.reverse()] = -count;
1005 }
1006 }
1007 return simplifiedEdges;
1008}
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
std::map< Edge, int > EdgeMap
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition SkVx.h:707

◆ test_crbug_1262444()

static void test_crbug_1262444 ( skiatest::Reporter r)
static

Definition at line 1179 of file TriangulatingPathRendererTests.cpp.

1179 {
1180 SkPath path;
1181
1182 path.setFillType(SkPathFillType::kWinding);
1183 path.moveTo(SkBits2Float(0x3fe0633f), SkBits2Float(0x3d04a60d)); // 1.75303f, 0.0323849f
1184 path.cubicTo(SkBits2Float(0x3fe27540), SkBits2Float(0x3dff593f), SkBits2Float(0x3fe45241),
1185 SkBits2Float(0x3e5e2fbb), SkBits2Float(0x3fe55b41), SkBits2Float(
1186 0x3e9e596d)); // 1.7692f, 0.124682f, 1.78376f, 0.216979f, 1.79185f, 0.309276f
1187 path.cubicTo(SkBits2Float(0x3fe5fa41), SkBits2Float(0x3eb3e79c), SkBits2Float(0x3fe62f41),
1188 SkBits2Float(0x3ec975cb), SkBits2Float(0x3fe69941), SkBits2Float(
1189 0x3edfd837)); // 1.7967f, 0.351376f, 1.79832f, 0.393477f, 1.80155f, 0.437196f
1190 path.cubicTo(SkBits2Float(0x3fe70341), SkBits2Float(0x3f064e87), SkBits2Float(0x3fe6ce41),
1191 SkBits2Float(0x3f1cb0f2), SkBits2Float(0x3fe59041), SkBits2Float(
1192 0x3f33135e)); // 1.80479f, 0.524636f, 1.80317f, 0.612075f, 1.79346f, 0.699514f
1193 path.cubicTo(SkBits2Float(0x3fe48740), SkBits2Float(0x3f468ef5), SkBits2Float(0x3fe2df40),
1194 SkBits2Float(0x3f59a06d), SkBits2Float(0x3fe02e3f), SkBits2Float(
1195 0x3f6cb1e6)); // 1.78538f, 0.775619f, 1.77244f, 0.850104f, 1.75141f, 0.92459f
1196 path.cubicTo(SkBits2Float(0x3fde863f), SkBits2Float(0x3f78b759), SkBits2Float(0x3fdc743e),
1197 SkBits2Float(0x3f822957), SkBits2Float(0x3fd9c33e), SkBits2Float(
1198 0x3f87f701)); // 1.73847f, 0.971548f, 1.7223f, 1.01689f, 1.70127f, 1.06223f
1199 path.cubicTo(SkBits2Float(0x3fd98e3e), SkBits2Float(0x3f88611f), SkBits2Float(0x3fd9593e),
1200 SkBits2Float(0x3f88cb3e), SkBits2Float(0x3fd9243d), SkBits2Float(
1201 0x3f896a6b)); // 1.69965f, 1.06546f, 1.69804f, 1.0687f, 1.69642f, 1.07356f
1202 path.cubicTo(SkBits2Float(0x3fd63e3c), SkBits2Float(0x3f8fa234), SkBits2Float(0x3fd2ee3b),
1203 SkBits2Float(0x3f95d9fd), SkBits2Float(0x3fd2ee3b), SkBits2Float(
1204 0x3f9ce602)); // 1.67377f, 1.12214f, 1.6479f, 1.17071f, 1.6479f, 1.22577f
1205 path.cubicTo(SkBits2Float(0x3fd3233b), SkBits2Float(0x3f9cb0f3), SkBits2Float(0x3fd3583b),
1206 SkBits2Float(0x3f9cb0f3), SkBits2Float(0x3fd3c23c), SkBits2Float(
1207 0x3f9c7be4)); // 1.64951f, 1.22415f, 1.65113f, 1.22415f, 1.65437f, 1.22253f
1208 path.cubicTo(SkBits2Float(0x3fd3c23c), SkBits2Float(0x3f9cb0f3), SkBits2Float(0x3fd3c23c),
1209 SkBits2Float(0x3f9cb0f3), SkBits2Float(0x3fd3c23c), SkBits2Float(
1210 0x3f9ce602)); // 1.65437f, 1.22415f, 1.65437f, 1.22415f, 1.65437f, 1.22577f
1211 path.cubicTo(SkBits2Float(0x3fd5353c), SkBits2Float(0x3f9c46d4), SkBits2Float(0x3fd6dd3d),
1212 SkBits2Float(0x3f9bdcb6), SkBits2Float(0x3fd7b13d), SkBits2Float(
1213 0x3f9ad36a)); // 1.66569f, 1.22091f, 1.67863f, 1.21767f, 1.6851f, 1.20958f
1214 path.cubicTo(SkBits2Float(0x3fda623e), SkBits2Float(0x3f96ae3a), SkBits2Float(0x3fdca93f),
1215 SkBits2Float(0x3f921eeb), SkBits2Float(0x3fdf253f), SkBits2Float(
1216 0x3f8dc4ab)); // 1.70612f, 1.17719f, 1.72391f, 1.14157f, 1.74332f, 1.10756f
1217 path.cubicTo(SkBits2Float(0x3fe0983f), SkBits2Float(0x3f8b12e5), SkBits2Float(0x3fe1d640),
1218 SkBits2Float(0x3f87f700), SkBits2Float(0x3fe3b340), SkBits2Float(
1219 0x3f857a4a)); // 1.75465f, 1.08651f, 1.76435f, 1.06223f, 1.77891f, 1.04279f
1220 path.cubicTo(SkBits2Float(0x3fe48740), SkBits2Float(0x3f8470fe), SkBits2Float(0x3fe62f40),
1221 SkBits2Float(0x3f8470fe), SkBits2Float(0x3fe7d741), SkBits2Float(
1222 0x3f843bef)); // 1.78538f, 1.0347f, 1.79832f, 1.0347f, 1.81126f, 1.03308f
1223 path.cubicTo(SkBits2Float(0x3fe2aa40), SkBits2Float(0x3f943182), SkBits2Float(0x3fda623d),
1224 SkBits2Float(0x3fa2498e), SkBits2Float(0x3fceff3a), SkBits2Float(
1225 0x3fae4f01)); // 1.77082f, 1.15776f, 1.70612f, 1.26787f, 1.61716f, 1.36179f
1226 path.cubicTo(SkBits2Float(0x3fce6039), SkBits2Float(0x3faf233e), SkBits2Float(0x3fcd2239),
1227 SkBits2Float(0x3faf584d), SkBits2Float(0x3fcc1939), SkBits2Float(
1228 0x3fafc26b)); // 1.61231f, 1.36826f, 1.60261f, 1.36988f, 1.59452f, 1.37312f
1229 path.cubicTo(SkBits2Float(0x3fcc1939), SkBits2Float(0x3faff77a), SkBits2Float(0x3fcc1939),
1230 SkBits2Float(0x3faff77a), SkBits2Float(0x3fcc4e39), SkBits2Float(
1231 0x3fb02c89)); // 1.59452f, 1.37474f, 1.59452f, 1.37474f, 1.59614f, 1.37636f
1232 path.cubicTo(SkBits2Float(0x3fcc1939), SkBits2Float(0x3fb02c89), SkBits2Float(0x3fcc1939),
1233 SkBits2Float(0x3fb02c89), SkBits2Float(0x3fcbe439), SkBits2Float(
1234 0x3fb02c89)); // 1.59452f, 1.37636f, 1.59452f, 1.37636f, 1.5929f, 1.37636f
1235 path.cubicTo(SkBits2Float(0x3fcbe439), SkBits2Float(0x3fb20a12), SkBits2Float(0x3fcb4539),
1236 SkBits2Float(0x3fb37d7d), SkBits2Float(0x3fc99d39), SkBits2Float(
1237 0x3fb3b28c)); // 1.5929f, 1.39093f, 1.58805f, 1.40227f, 1.57511f, 1.40389f
1238 path.cubicTo(SkBits2Float(0x3fc93339), SkBits2Float(0x3fb3e79b), SkBits2Float(0x3fc8c938),
1239 SkBits2Float(0x3fb41caa), SkBits2Float(0x3fc7f538), SkBits2Float(
1240 0x3fb41caa)); // 1.57188f, 1.40551f, 1.56864f, 1.40712f, 1.56217f, 1.40712f
1241 path.cubicTo(SkBits2Float(0x3fc7f538), SkBits2Float(0x3fb3e79b), SkBits2Float(0x3fc7f538),
1242 SkBits2Float(0x3fb3e79b), SkBits2Float(0x3fc7f538), SkBits2Float(
1243 0x3fb3b28c)); // 1.56217f, 1.40551f, 1.56217f, 1.40551f, 1.56217f, 1.40389f
1244 path.lineTo(SkBits2Float(0x3fc7c038), SkBits2Float(0x3fb3b28c)); // 1.56055f, 1.40389f
1245 path.cubicTo(SkBits2Float(0x3fc7c038), SkBits2Float(0x3fb4f0e7), SkBits2Float(0x3fc7f538),
1246 SkBits2Float(0x3fb66452), SkBits2Float(0x3fc78b38), SkBits2Float(
1247 0x3fb76d9e)); // 1.56055f, 1.4136f, 1.56217f, 1.42494f, 1.55894f, 1.43303f
1248 path.cubicTo(SkBits2Float(0x3fc3d137), SkBits2Float(0x3fbe4495), SkBits2Float(0x3fbf4336),
1249 SkBits2Float(0x3fc4123e), SkBits2Float(0x3fb80434), SkBits2Float(
1250 0x3fc76331)); // 1.52982f, 1.48647f, 1.49424f, 1.53181f, 1.43763f, 1.55771f
1251 path.cubicTo(SkBits2Float(0x3fb47f33), SkBits2Float(0x3fc90bac), SkBits2Float(0x3fb19932),
1252 SkBits2Float(0x3fcb5353), SkBits2Float(0x3faf1d31), SkBits2Float(
1253 0x3fce6f37)); // 1.41013f, 1.57067f, 1.38749f, 1.58848f, 1.36808f, 1.61277f
1254 path.cubicTo(SkBits2Float(0x3fa4592e), SkBits2Float(0x3fdb13d7), SkBits2Float(0x3f974e2a),
1255 SkBits2Float(0x3fe53bc1), SkBits2Float(0x3f896f25), SkBits2Float(
1256 0x3fee5a5f)); // 1.28397f, 1.71154f, 1.18207f, 1.79089f, 1.0737f, 1.86213f
1257 path.cubicTo(SkBits2Float(0x3f6b883f), SkBits2Float(0x3ffb691f), SkBits2Float(0x3f42f434),
1258 SkBits2Float(0x400367b2), SkBits2Float(0x3f184e28), SkBits2Float(
1259 0x4008611f)); // 0.920048f, 1.96415f, 0.761539f, 2.0532f, 0.594943f, 2.13093f
1260 path.cubicTo(SkBits2Float(0x3f184e28), SkBits2Float(0x4008611f), SkBits2Float(0x3f17e428),
1261 SkBits2Float(0x4008611f), SkBits2Float(0x3f17e428), SkBits2Float(
1262 0x40087ba7)); // 0.594943f, 2.13093f, 0.593325f, 2.13093f, 0.593325f, 2.13255f
1263 path.cubicTo(SkBits2Float(0x3effc044), SkBits2Float(0x400b47f5), SkBits2Float(0x3ed08c36),
1264 SkBits2Float(0x400e2eca), SkBits2Float(0x3e9edc28), SkBits2Float(
1265 0x401090f9)); // 0.499514f, 2.17627f, 0.40732f, 2.22161f, 0.310273f, 2.25885f
1266 path.cubicTo(SkBits2Float(0x3e5a5832), SkBits2Float(0x4012f328), SkBits2Float(0x3de40030),
1267 SkBits2Float(0x4014811a), SkBits2Float(0x3c1a7f9e), SkBits2Float(
1268 0x40158a66)); // 0.213227f, 2.29609f, 0.111328f, 2.32038f, 0.00942984f, 2.33657f
1269 path.lineTo(SkBits2Float(0x3c1a7f9e), SkBits2Float(0x401bf73d)); // 0.00942984f, 2.43697f
1270 path.cubicTo(SkBits2Float(0x3dc98028), SkBits2Float(0x401b580f), SkBits2Float(0x3e3fd82e),
1271 SkBits2Float(0x401a694b), SkBits2Float(0x3e8ca424), SkBits2Float(
1272 0x40191068)); // 0.098389f, 2.42725f, 0.187348f, 2.41268f, 0.27469f, 2.39163f
1273 path.cubicTo(SkBits2Float(0x3e94ec27), SkBits2Float(0x4018db59), SkBits2Float(0x3e9d3429),
1274 SkBits2Float(0x40188bc2), SkBits2Float(0x3ea4a82b), SkBits2Float(
1275 0x401856b3)); // 0.290864f, 2.38839f, 0.307039f, 2.38353f, 0.321596f, 2.38029f
1276 path.cubicTo(SkBits2Float(0x3eae982e), SkBits2Float(0x4018071c), SkBits2Float(0x3eb95c31),
1277 SkBits2Float(0x40179cfe), SkBits2Float(0x3ec34c34), SkBits2Float(
1278 0x40174d67)); // 0.341005f, 2.37543f, 0.362031f, 2.36896f, 0.381441f, 2.3641f
1279 path.cubicTo(SkBits2Float(0x3ec9ec36), SkBits2Float(0x40171858), SkBits2Float(0x3ed08c38),
1280 SkBits2Float(0x4016c8c1), SkBits2Float(0x3ed8003a), SkBits2Float(
1281 0x401693b2)); // 0.39438f, 2.36086f, 0.40732f, 2.356f, 0.421877f, 2.35276f
1282 path.cubicTo(SkBits2Float(0x3eda7c3a), SkBits2Float(0x4016792a), SkBits2Float(0x3eddcc3c),
1283 SkBits2Float(0x40165ea3), SkBits2Float(0x3ee0483c), SkBits2Float(
1284 0x4016441b)); // 0.426729f, 2.35115f, 0.433199f, 2.34953f, 0.438051f, 2.34791f
1285 path.cubicTo(SkBits2Float(0x3ee2c43d), SkBits2Float(0x40162993), SkBits2Float(0x3ee5403e),
1286 SkBits2Float(0x40160f0c), SkBits2Float(0x3ee8903f), SkBits2Float(
1287 0x4015f484)); // 0.442903f, 2.34629f, 0.447756f, 2.34467f, 0.454226f, 2.34305f
1288 path.cubicTo(SkBits2Float(0x3f1c082a), SkBits2Float(0x4012be17), SkBits2Float(0x3f422036),
1289 SkBits2Float(0x400e63d8), SkBits2Float(0x3f66fa40), SkBits2Float(
1290 0x40096a6a)); // 0.6095f, 2.29285f, 0.758304f, 2.22484f, 0.902256f, 2.14712f
1291 path.cubicTo(SkBits2Float(0x3f6a4a41), SkBits2Float(0x4009004c), SkBits2Float(0x3f6d3042),
1292 SkBits2Float(0x4008962d), SkBits2Float(0x3f708043), SkBits2Float(
1293 0x40081187)); // 0.915196f, 2.14064f, 0.926518f, 2.13417f, 0.939457f, 2.12607f
1294 path.cubicTo(SkBits2Float(0x3f7efe47), SkBits2Float(0x4005feef), SkBits2Float(0x3f868925),
1295 SkBits2Float(0x4003b748), SkBits2Float(0x3f8d5e28), SkBits2Float(
1296 0x40015519)); // 0.996067f, 2.09368f, 1.05106f, 2.05806f, 1.10444f, 2.02082f
1297 path.cubicTo(SkBits2Float(0x3f97b82b), SkBits2Float(0x3ffb691d), SkBits2Float(0x3fa1a82e),
1298 SkBits2Float(0x3ff388da), SkBits2Float(0x3fab9830), SkBits2Float(
1299 0x3feb7389)); // 1.18531f, 1.96415f, 1.26294f, 1.90261f, 1.34058f, 1.83946f
1300 path.cubicTo(SkBits2Float(0x3fb20332), SkBits2Float(0x3fe6450c), SkBits2Float(0x3fb80434),
1301 SkBits2Float(0x3fe0e181), SkBits2Float(0x3fbd6635), SkBits2Float(
1302 0x3fda3f99)); // 1.39072f, 1.79898f, 1.43763f, 1.75688f, 1.47968f, 1.70507f
1303 path.cubicTo(SkBits2Float(0x3fbf4336), SkBits2Float(0x3fd7f7f2), SkBits2Float(0x3fc12037),
1304 SkBits2Float(0x3fd5b04b), SkBits2Float(0x3fc2fd36), SkBits2Float(
1305 0x3fd33394)); // 1.49424f, 1.68725f, 1.5088f, 1.66944f, 1.52335f, 1.65001f
1306 path.cubicTo(SkBits2Float(0x3fc5e337), SkBits2Float(0x3fcf7881), SkBits2Float(0x3fc8c938),
1307 SkBits2Float(0x3fcbbd70), SkBits2Float(0x3fcbaf38), SkBits2Float(
1308 0x3fc8025d)); // 1.546f, 1.62086f, 1.56864f, 1.59172f, 1.59128f, 1.56257f
1309 path.cubicTo(SkBits2Float(0x3fceff39), SkBits2Float(0x3fc3a81e), SkBits2Float(0x3fd2843b),
1310 SkBits2Float(0x3fbf18cf), SkBits2Float(0x3fd5d43b), SkBits2Float(
1311 0x3fbabe8f)); // 1.61716f, 1.52857f, 1.64466f, 1.49294f, 1.67054f, 1.45894f
1312 path.cubicTo(SkBits2Float(0x3fd8503c), SkBits2Float(0x3fb7a2ab), SkBits2Float(0x3fda973d),
1313 SkBits2Float(0x3fb486c7), SkBits2Float(0x3fdca93e), SkBits2Float(
1314 0x3fb135d3)); // 1.68995f, 1.43465f, 1.70774f, 1.41036f, 1.72391f, 1.38446f
1315 path.cubicTo(SkBits2Float(0x3fe5c541), SkBits2Float(0x3fa2b3aa), SkBits2Float(0x3feb5c42),
1316 SkBits2Float(0x3f92be16), SkBits2Float(0x3ff15d44), SkBits2Float(
1317 0x3f82c882)); // 1.79508f, 1.27111f, 1.83875f, 1.14643f, 1.88566f, 1.02174f
1318 path.cubicTo(SkBits2Float(0x3ff1fc44), SkBits2Float(0x3f812008), SkBits2Float(0x3ff23144),
1319 SkBits2Float(0x3f7e1adf), SkBits2Float(0x3ff29b44), SkBits2Float(
1320 0x3f7a5fcc)); // 1.89051f, 1.00879f, 1.89213f, 0.992598f, 1.89536f, 0.978024f
1321 path.cubicTo(SkBits2Float(0x3ff47845), SkBits2Float(0x3f5fd830), SkBits2Float(0x3ff65545),
1322 SkBits2Float(0x3f455094), SkBits2Float(0x3ff6bf45), SkBits2Float(
1323 0x3f2a5ed9)); // 1.90992f, 0.874393f, 1.92448f, 0.770761f, 1.92771f, 0.66551f
1324 path.cubicTo(SkBits2Float(0x3ff33a44), SkBits2Float(0x3f0d5a87), SkBits2Float(0x3ff08943),
1325 SkBits2Float(0x3edf03ee), SkBits2Float(0x3fee7743), SkBits2Float(
1326 0x3ea352cf)); // 1.90022f, 0.552163f, 1.87919f, 0.435577f, 1.86301f, 0.318991f
1327 path.cubicTo(SkBits2Float(0x3feccf42), SkBits2Float(0x3e5c872d), SkBits2Float(0x3feb9142),
1328 SkBits2Float(0x3de4d179), SkBits2Float(0x3feaf242), SkBits2Float(
1329 0x3c04a4ae)); // 1.85008f, 0.215359f, 1.84037f, 0.111728f, 1.83552f, 0.0080959f
1330 path.lineTo(SkBits2Float(0x3fe02e3f), SkBits2Float(0x3c04a4ae)); // 1.75141f, 0.0080959f
1331 path.cubicTo(SkBits2Float(0x3fdff93f), SkBits2Float(0x3c6ec47e), SkBits2Float(0x3fe02e3f),
1332 SkBits2Float(0x3cb9b545), SkBits2Float(0x3fe0633f), SkBits2Float(
1333 0x3d04a60d)); // 1.74979f, 0.0145732f, 1.75141f, 0.0226694f, 1.75303f, 0.0323849f
1334 path.close();
1335 path.moveTo(SkBits2Float(0x3fe97f42), SkBits2Float(0x3f7b9e2e)); // 1.8242f, 0.982882f
1336 path.cubicTo(SkBits2Float(0x3fe91542), SkBits2Float(0x3f7eef21), SkBits2Float(0x3fe87642),
1337 SkBits2Float(0x3f81551a), SkBits2Float(0x3fe7d741), SkBits2Float(
1338 0x3f82fd94)); // 1.82096f, 0.995836f, 1.81611f, 1.01041f, 1.81126f, 1.02336f
1339 path.cubicTo(SkBits2Float(0x3fe6ce41), SkBits2Float(0x3f81bf39), SkBits2Float(0x3fe66441),
1340 SkBits2Float(0x3f8080dd), SkBits2Float(0x3fe66441), SkBits2Float(
1341 0x3f7e1ae4)); // 1.80317f, 1.01365f, 1.79993f, 1.00393f, 1.79993f, 0.992598f
1342 path.cubicTo(SkBits2Float(0x3fe66441), SkBits2Float(0x3f7c726a), SkBits2Float(0x3fe69941),
1343 SkBits2Float(0x3f7b340e), SkBits2Float(0x3fe6ce41), SkBits2Float(
1344 0x3f798b95)); // 1.79993f, 0.986121f, 1.80155f, 0.981263f, 1.80317f, 0.974786f
1345 path.cubicTo(SkBits2Float(0x3fe70341), SkBits2Float(0x3f78b758), SkBits2Float(0x3fe76d41),
1346 SkBits2Float(0x3f770edf), SkBits2Float(0x3fe7d741), SkBits2Float(
1347 0x3f770edf)); // 1.80479f, 0.971548f, 1.80802f, 0.965071f, 1.81126f, 0.965071f
1348 path.cubicTo(SkBits2Float(0x3fe84141), SkBits2Float(0x3f770edf), SkBits2Float(0x3fe8ab42),
1349 SkBits2Float(0x3f770edf), SkBits2Float(0x3fe8e041), SkBits2Float(
1350 0x3f7778fd)); // 1.81449f, 0.965071f, 1.81773f, 0.965071f, 1.81934f, 0.96669f
1351 path.cubicTo(SkBits2Float(0x3fe97f42), SkBits2Float(0x3f77e31b), SkBits2Float(0x3fe9e942),
1352 SkBits2Float(0x3f798b95), SkBits2Float(0x3fe97f42), SkBits2Float(
1353 0x3f7b9e2e)); // 1.8242f, 0.968309f, 1.82743f, 0.974786f, 1.8242f, 0.982882f
1354 path.close();
1355
1356 float kTol = 0.25f;
1357 SkRect clipBounds = SkRect::MakeLTRB(0, 0, 14, 14);
1358 SimplerVertexAllocator alloc;
1359
1360 int vertexCount = GrAATriangulator::PathToAATriangles(path, kTol, clipBounds, &alloc);
1361 REPORTER_ASSERT(r, vertexCount == 0);
1362}
static float SkBits2Float(uint32_t bits)
Definition SkFloatBits.h:48
static int PathToAATriangles(const SkPath &path, SkScalar tolerance, const SkRect &clipBounds, GrEagerVertexAllocator *vertexAllocator)
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
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646

◆ verify_simple_inner_polygons()

static void verify_simple_inner_polygons ( skiatest::Reporter r,
const char *  shapeName,
SkPath  path 
)
static

Definition at line 1010 of file TriangulatingPathRendererTests.cpp.

1011 {
1012 for (auto fillType : {SkPathFillType::kWinding}) {
1013 path.setFillType(fillType);
1016 SimpleVertexAllocator vertexAlloc;
1017 int vertexCount;
1018 {
1019 bool isLinear;
1020 GrInnerFanTriangulator triangulator(path, &arena);
1021 vertexCount = triangulator.pathToTriangles(&vertexAlloc, &breadcrumbs, &isLinear);
1022 }
1023
1024 // Count up all the triangulated edges.
1025 EdgeMap trianglePlusBreadcrumbEdges;
1026 for (int i = 0; i < vertexCount; i += 3) {
1027 add_tri_edges(r, trianglePlusBreadcrumbEdges, vertexAlloc.fPoints.data() + i);
1028 }
1029 // Count up all the breadcrumb edges.
1030 int breadcrumbCount = 0;
1031 for (const auto* node = breadcrumbs.head(); node; node = node->fNext) {
1032 add_tri_edges(r, trianglePlusBreadcrumbEdges, node->fPts);
1033 ++breadcrumbCount;
1034 }
1035 REPORTER_ASSERT(r, breadcrumbCount == breadcrumbs.count());
1036 // The triangulated + breadcrumb edges should cancel out to the inner polygon edges.
1037 trianglePlusBreadcrumbEdges = simplify(trianglePlusBreadcrumbEdges, path.getFillType());
1038
1039 // Build the inner polygon edges.
1040 EdgeMap innerFanEdges;
1041 SkPoint startPoint{}, lastPoint{};
1042 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
1043 switch (verb) {
1044 case SkPathVerb::kMove:
1045 if (lastPoint != startPoint) {
1046 add_edge(innerFanEdges, lastPoint, startPoint);
1047 }
1048 lastPoint = startPoint = pts[0];
1049 continue;
1050 case SkPathVerb::kClose:
1051 lastPoint = startPoint;
1052 break;
1053 case SkPathVerb::kLine:
1054 lastPoint = pts[1];
1055 break;
1056 case SkPathVerb::kQuad:
1057 case SkPathVerb::kConic:
1058 lastPoint = pts[2];
1059 break;
1060 case SkPathVerb::kCubic:
1061 lastPoint = pts[3];
1062 break;
1063 }
1064 if (pts[0] != lastPoint) {
1065 add_edge(innerFanEdges, pts[0], lastPoint);
1066 }
1067 }
1068 if (lastPoint != startPoint) {
1069 add_edge(innerFanEdges, lastPoint, startPoint);
1070 }
1071 innerFanEdges = simplify(innerFanEdges, path.getFillType());
1072
1073 // The triangulated + breadcrumb edges should cancel out to the inner polygon edges. First
1074 // verify that every inner polygon edge can be found in the triangulation.
1075 for (auto [edge, count] : innerFanEdges) {
1076 auto it = trianglePlusBreadcrumbEdges.find(edge);
1077 if (it != trianglePlusBreadcrumbEdges.end()) {
1078 it->second -= count;
1079 if (it->second == 0) {
1080 trianglePlusBreadcrumbEdges.erase(it);
1081 }
1082 continue;
1083 }
1084 it = trianglePlusBreadcrumbEdges.find(edge.reverse());
1085 if (it != trianglePlusBreadcrumbEdges.end()) {
1086 it->second += count;
1087 if (it->second == 0) {
1088 trianglePlusBreadcrumbEdges.erase(it);
1089 }
1090 continue;
1091 }
1092 ERRORF(r, "error: %s: edge [%g,%g]:[%g,%g] not found in triangulation.",
1093 shapeName, edge.fP0.fX, edge.fP0.fY, edge.fP1.fX, edge.fP1.fY);
1094 return;
1095 }
1096 // Now verify that there are no spurious edges in the triangulation.
1097 //
1098 // NOTE: The triangulator's definition of wind isn't always correct for edges that run
1099 // exactly parallel to the sweep (either vertical or horizontal edges). This doesn't
1100 // actually matter though because T-junction artifacts don't happen on axis-aligned edges.
1101 // Tolerate spurious edges that (1) come in pairs of 2, and (2) are either exactly
1102 // horizontal or exactly vertical exclusively.
1103 bool hasSpuriousHorz=false, hasSpuriousVert=false;
1104 for (auto [edge, count] : trianglePlusBreadcrumbEdges) {
1105 if (count % 2 == 0) {
1106 if (edge.fP0.fX == edge.fP1.fX && !hasSpuriousVert) {
1107 hasSpuriousHorz = true;
1108 continue;
1109 }
1110 if (edge.fP0.fY == edge.fP1.fY && !hasSpuriousHorz) {
1111 hasSpuriousVert = true;
1112 continue;
1113 }
1114 }
1115 ERRORF(r, "error: %s: spurious edge [%g,%g]:[%g,%g] found in triangulation.",
1116 shapeName, edge.fP0.fX, edge.fP0.fY, edge.fP1.fX, edge.fP1.fY);
1117 return;
1118 }
1119 }
1120}
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
#define ERRORF(r,...)
Definition Test.h:293
static EdgeMap simplify(const EdgeMap &edges, SkPathFillType fillType)
static void add_tri_edges(skiatest::Reporter *r, EdgeMap &edgeMap, const SkPoint pts[3])
static constexpr int kArenaDefaultChunkSize
SkScalar w

Variable Documentation

◆ kNonEdgeAAPaths

CreatePathFn kNonEdgeAAPaths[]

Definition at line 76 of file TriangulatingPathRendererTests.cpp.

76 {
77 // Tests active edges made inactive by splitting.
78 // Also tests active edge list forced into an invalid ordering by
79 // splitting (mopped up in cleanup_active_edges()).
80 []() -> SkPath {
82 path.moveTo(229.127044677734375f, 67.34100341796875f);
83 path.lineTo(187.8097381591796875f, -6.7729740142822265625f);
84 path.lineTo(171.411407470703125f, 50.94266510009765625f);
85 path.lineTo(245.5253753662109375f, 9.6253643035888671875f);
86 path.moveTo(208.4683990478515625f, 30.284009933471679688f);
87 path.lineTo(171.411407470703125f, 50.94266510009765625f);
88 path.lineTo(187.8097381591796875f, -6.7729740142822265625f);
89 return path;
90 },
91
92 // Intersections which fall exactly on the current vertex, and require
93 // a restart of the intersection checking.
94 []() -> SkPath {
96 path.moveTo(314.483551025390625f, 486.246002197265625f);
97 path.lineTo(385.41949462890625f, 532.8087158203125f);
98 path.lineTo(373.232879638671875f, 474.05938720703125f);
99 path.lineTo(326.670166015625f, 544.995361328125f);
100 path.moveTo(349.951507568359375f, 509.52734375f);
101 path.lineTo(373.232879638671875f, 474.05938720703125f);
102 path.lineTo(385.41949462890625f, 532.8087158203125f);
103 return path;
104 },
105
106 // Tests active edges which are removed by splitting.
107 []() -> SkPath {
108 SkPath path;
109 path.moveTo(343.107391357421875f, 613.62176513671875f);
110 path.lineTo(426.632415771484375f, 628.5740966796875f);
111 path.lineTo(392.3460693359375f, 579.33544921875f);
112 path.lineTo(377.39373779296875f, 662.86041259765625f);
113 path.moveTo(384.869873046875f, 621.097900390625f);
114 path.lineTo(392.3460693359375f, 579.33544921875f);
115 path.lineTo(426.632415771484375f, 628.5740966796875f);
116 return path;
117 },
118
119 // Collinear edges merged in set_top().
120 // Also, an intersection between left and right enclosing edges which
121 // falls above the current vertex.
122 []() -> SkPath {
123 SkPath path;
124 path.moveTo(545.95751953125f, 791.69854736328125f);
125 path.lineTo(612.05816650390625f, 738.494140625f);
126 path.lineTo(552.4056396484375f, 732.0460205078125f);
127 path.lineTo(605.61004638671875f, 798.14666748046875f);
128 path.moveTo(579.00787353515625f, 765.0963134765625f);
129 path.lineTo(552.4056396484375f, 732.0460205078125f);
130 path.lineTo(612.05816650390625f, 738.494140625f);
131 return path;
132 },
133
134 // Tests active edges which are made inactive by set_top().
135 []() -> SkPath {
136 SkPath path;
137 path.moveTo(819.2725830078125f, 751.77447509765625f);
138 path.lineTo(820.70904541015625f, 666.933837890625f);
139 path.lineTo(777.57049560546875f, 708.63592529296875f);
140 path.lineTo(862.4111328125f, 710.0723876953125f);
141 path.moveTo(819.99078369140625f, 709.3541259765625f);
142 path.lineTo(777.57049560546875f, 708.63592529296875f);
143 path.lineTo(820.70904541015625f, 666.933837890625f);
144 return path;
145 },
146
147 []() -> SkPath {
148 SkPath path;
149 path.moveTo(823.33209228515625f, 749.052734375f);
150 path.lineTo(823.494873046875f, 664.20013427734375f);
151 path.lineTo(780.9871826171875f, 706.5450439453125f);
152 path.lineTo(865.8397216796875f, 706.70782470703125f);
153 path.moveTo(823.4134521484375f, 706.6263427734375f);
154 path.lineTo(780.9871826171875f, 706.5450439453125f);
155 path.lineTo(823.494873046875f, 664.20013427734375f);
156 return path;
157 },
158
159 []() -> SkPath {
160 SkPath path;
161 path.moveTo(954.862548828125f, 562.8349609375f);
162 path.lineTo(899.32818603515625f, 498.679443359375f);
163 path.lineTo(895.017578125f, 558.52435302734375f);
164 path.lineTo(959.17315673828125f, 502.990081787109375f);
165 path.moveTo(927.0953369140625f, 530.7572021484375f);
166 path.lineTo(895.017578125f, 558.52435302734375f);
167 path.lineTo(899.32818603515625f, 498.679443359375f);
168 return path;
169 },
170
171 []() -> SkPath {
172 SkPath path;
173 path.moveTo(958.5330810546875f, 547.35516357421875f);
174 path.lineTo(899.93109130859375f, 485.989013671875f);
175 path.lineTo(898.54901123046875f, 545.97308349609375f);
176 path.lineTo(959.9151611328125f, 487.37109375f);
177 path.moveTo(929.2320556640625f, 516.67205810546875f);
178 path.lineTo(898.54901123046875f, 545.97308349609375f);
179 path.lineTo(899.93109130859375f, 485.989013671875f);
180 return path;
181 },
182
183 []() -> SkPath {
184 SkPath path;
185 path.moveTo(389.8609619140625f, 369.326873779296875f);
186 path.lineTo(470.6290283203125f, 395.33697509765625f);
187 path.lineTo(443.250030517578125f, 341.9478759765625f);
188 path.lineTo(417.239959716796875f, 422.7159423828125f);
189 path.moveTo(430.244964599609375f, 382.3319091796875f);
190 path.lineTo(443.250030517578125f, 341.9478759765625f);
191 path.lineTo(470.6290283203125f, 395.33697509765625f);
192 return path;
193 },
194
195 []() -> SkPath {
196 SkPath path;
197 path.moveTo(20, 20);
198 path.lineTo(50, 80);
199 path.lineTo(20, 80);
200 path.moveTo(80, 50);
201 path.lineTo(50, 50);
202 path.lineTo(20, 50);
203 return path;
204 },
205
206 []() -> SkPath {
207 SkPath path;
208 path.moveTo(257.19439697265625f, 320.876617431640625f);
209 path.lineTo(190.113037109375f, 320.58978271484375f);
210 path.lineTo(203.64404296875f, 293.8145751953125f);
211 path.moveTo(203.357177734375f, 360.896026611328125f);
212 path.lineTo(216.88824462890625f, 334.120819091796875f);
213 path.lineTo(230.41925048828125f, 307.345611572265625f);
214 return path;
215 },
216
217 // A degenerate segments case, where both upper and lower segments of
218 // a split edge must remain active.
219 []() -> SkPath {
220 SkPath path;
221 path.moveTo(231.9331207275390625f, 306.2012939453125f);
222 path.lineTo(191.4859161376953125f, 306.04547119140625f);
223 path.lineTo(231.0659332275390625f, 300.2642822265625f);
224 path.moveTo(189.946807861328125f, 302.072265625f);
225 path.lineTo(179.79705810546875f, 294.859771728515625f);
226 path.lineTo(191.0016021728515625f, 296.165679931640625f);
227 path.moveTo(150.8942108154296875f, 304.900146484375f);
228 path.lineTo(179.708892822265625f, 297.849029541015625f);
229 path.lineTo(190.4742279052734375f, 299.11895751953125f);
230 return path;
231 },
232
233 // Handle the case where edge.dist(edge.fTop) != 0.0.
234 []() -> SkPath {
235 SkPath path;
236 path.moveTo( 0.0f, 400.0f);
237 path.lineTo( 138.0f, 202.0f);
238 path.lineTo( 0.0f, 202.0f);
239 path.moveTo( 12.62693023681640625f, 250.57464599609375f);
240 path.lineTo( 8.13896942138671875f, 254.556884765625f);
241 path.lineTo(-18.15641021728515625f, 220.40203857421875f);
242 path.lineTo(-15.986493110656738281f, 219.6513519287109375f);
243 path.moveTo( 36.931194305419921875f, 282.485504150390625f);
244 path.lineTo( 15.617521286010742188f, 261.2901611328125f);
245 path.lineTo( 10.3829498291015625f, 252.565765380859375f);
246 path.lineTo(-16.165292739868164062f, 222.646026611328125f);
247 return path;
248 },
249
250 // A degenerate segments case which exercises inactive edges being
251 // made active by splitting.
252 []() -> SkPath {
253 SkPath path;
254 path.moveTo(690.62127685546875f, 509.25555419921875f);
255 path.lineTo(99.336181640625f, 511.71405029296875f);
256 path.lineTo(708.362548828125f, 512.4349365234375f);
257 path.lineTo(729.9940185546875f, 516.3114013671875f);
258 path.lineTo(738.708984375f, 518.76995849609375f);
259 path.lineTo(678.3463134765625f, 510.0819091796875f);
260 path.lineTo(681.21795654296875f, 504.81378173828125f);
261 path.moveTo(758.52764892578125f, 521.55963134765625f);
262 path.lineTo(719.1549072265625f, 514.50372314453125f);
263 path.lineTo(689.59063720703125f, 512.0628662109375f);
264 path.lineTo(679.78216552734375f, 507.447845458984375f);
265 return path;
266 },
267
268 // Tests vertices which become "orphaned" (ie., no connected edges)
269 // after simplification.
270 []() -> SkPath {
271 SkPath path;
272 path.moveTo(217.326019287109375f, 166.4752960205078125f);
273 path.lineTo(226.279266357421875f, 170.929473876953125f);
274 path.lineTo(234.3973388671875f, 177.0623626708984375f);
275 path.lineTo(262.0921630859375f, 188.746124267578125f);
276 path.moveTo(196.23638916015625f, 174.0722198486328125f);
277 path.lineTo(416.15277099609375f, 180.138214111328125f);
278 path.lineTo(192.651947021484375f, 304.0228271484375f);
279 return path;
280 },
281
282 []() -> SkPath {
283 SkPath path;
284 path.moveTo( 0.0f, 0.0f);
285 path.lineTo(10000.0f, 0.0f);
286 path.lineTo( 0.0f, -1.0f);
287 path.lineTo(10000.0f, 0.000001f);
288 path.lineTo( 0.0f, -30.0f);
289 return path;
290 },
291
292 // Reduction of Nebraska-StateSeal.svg. Floating point error causes the
293 // same edge to be added to more than one poly on the same side.
294 []() -> SkPath {
295 SkPath path;
296 path.moveTo(170.8199920654296875, 491.86700439453125);
297 path.lineTo(173.7649993896484375, 489.7340087890625);
298 path.lineTo(174.1450958251953125, 498.545989990234375);
299 path.lineTo( 171.998992919921875, 500.88201904296875);
300 path.moveTo(168.2922515869140625, 498.66265869140625);
301 path.lineTo(169.8589935302734375, 497.94500732421875);
302 path.lineTo( 172, 500.88299560546875);
303 path.moveTo( 169.555267333984375, 490.70111083984375);
304 path.lineTo(173.7649993896484375, 489.7340087890625);
305 path.lineTo( 170.82000732421875, 491.86700439453125);
306 return path;
307 },
308
309 // A shape with a vertex collinear to the right hand edge.
310 // This messes up find_enclosing_edges.
311 []() -> SkPath {
312 SkPath path;
313 path.moveTo(80, 20);
314 path.lineTo(80, 60);
315 path.lineTo(20, 60);
316 path.moveTo(80, 50);
317 path.lineTo(80, 80);
318 path.lineTo(20, 80);
319 return path;
320 },
321
322 // Exercises the case where an edge becomes collinear with *two* of its
323 // adjacent neighbour edges after splitting.
324 // This is a reduction from
325 // http://mooooo.ooo/chebyshev-sine-approximation/horner_ulp.svg
326 []() -> SkPath {
327 SkPath path;
328 path.moveTo( 351.99298095703125, 348.23046875);
329 path.lineTo( 351.91876220703125, 347.33984375);
330 path.lineTo( 351.91876220703125, 346.1953125);
331 path.lineTo( 351.90313720703125, 347.734375);
332 path.lineTo( 351.90313720703125, 346.1328125);
333 path.lineTo( 351.87579345703125, 347.93359375);
334 path.lineTo( 351.87579345703125, 345.484375);
335 path.lineTo( 351.86407470703125, 347.7890625);
336 path.lineTo( 351.86407470703125, 346.2109375);
337 path.lineTo( 351.84844970703125, 347.63763427734375);
338 path.lineTo( 351.84454345703125, 344.19232177734375);
339 path.lineTo( 351.78204345703125, 346.9483642578125);
340 path.lineTo( 351.758636474609375, 347.18310546875);
341 path.lineTo( 351.75469970703125, 346.75);
342 path.lineTo( 351.75469970703125, 345.46875);
343 path.lineTo( 352.5546875, 345.46875);
344 path.lineTo( 352.55078125, 347.01953125);
345 path.lineTo( 351.75079345703125, 347.02313232421875);
346 path.lineTo( 351.74688720703125, 346.15203857421875);
347 path.lineTo( 351.74688720703125, 347.646148681640625);
348 path.lineTo( 352.5390625, 346.94140625);
349 path.lineTo( 351.73907470703125, 346.94268798828125);
350 path.lineTo( 351.73516845703125, 344.48565673828125);
351 path.lineTo( 352.484375, 346.73828125);
352 path.lineTo( 351.68438720703125, 346.7401123046875);
353 path.lineTo( 352.4765625, 346.546875);
354 path.lineTo( 351.67657470703125, 346.54937744140625);
355 path.lineTo( 352.47265625, 346.75390625);
356 path.lineTo( 351.67266845703125, 346.756622314453125);
357 path.lineTo( 351.66876220703125, 345.612091064453125);
358 return path;
359 },
360
361 // A path which contains out-of-range colinear intersections.
362 []() -> SkPath {
363 SkPath path;
364 path.moveTo( 0, 63.39080047607421875);
365 path.lineTo(-0.70804601907730102539, 63.14350128173828125);
366 path.lineTo(-7.8608899287380243391e-17, 64.14080047607421875);
367 path.moveTo( 0, 64.14080047607421875);
368 path.lineTo(44.285900115966796875, 64.14080047607421875);
369 path.lineTo( 0, 62.64080047607421875);
370 path.moveTo(21.434900283813476562, -0.24732701480388641357);
371 path.lineTo(-0.70804601907730102539, 63.14350128173828125);
372 path.lineTo(0.70804601907730102539, 63.6381988525390625);
373 return path;
374 },
375
376 // A path which results in infs and nans when conics are converted to quads.
377 []() -> SkPath {
378 SkPath path;
379 path.moveTo(-2.20883e+37f, -1.02892e+37f);
380 path.conicTo(-2.00958e+38f, -9.36107e+37f, -1.7887e+38f, -8.33215e+37f, 0.707107f);
381 path.conicTo(-1.56782e+38f, -7.30323e+37f, 2.20883e+37f, 1.02892e+37f, 0.707107f);
382 path.conicTo(2.00958e+38f, 9.36107e+37f, 1.7887e+38f, 8.33215e+37f, 0.707107f);
383 path.conicTo(1.56782e+38f, 7.30323e+37f, -2.20883e+37f, -1.02892e+37f, 0.707107f);
384 return path;
385 },
386
387 // A quad which generates a huge number of points (>2B) when uniformly
388 // linearized. This should not hang or OOM.
389 []() -> SkPath {
390 SkPath path;
391 path.moveTo(10, 0);
392 path.lineTo(0, 0);
393 path.quadTo(10, 0, 0, 8315084722602508288);
394 return path;
395 },
396
397 // A path which hangs during simplification. It produces an edge which is
398 // to the left of its own endpoints, which causes an infinite loop in the
399 // right-enclosing-edge splitting.
400 []() -> SkPath {
401 SkPath path;
402 path.moveTo(0.75001740455627441406, 23.051967620849609375);
403 path.lineTo(5.8471612930297851562, 22.731662750244140625);
404 path.lineTo(10.749670028686523438, 22.253145217895507812);
405 path.lineTo(13.115868568420410156, 22.180681228637695312);
406 path.lineTo(15.418928146362304688, 22.340015411376953125);
407 path.lineTo( 17.654022216796875, 22.82159423828125);
408 path.lineTo(19.81632232666015625, 23.715869903564453125);
409 path.lineTo(40, 0);
410 path.lineTo(5.5635203441547955577e-15, 0);
411 path.lineTo(5.5635203441547955577e-15, 47);
412 path.lineTo(-1.4210854715202003717e-14, 21.713298797607421875);
413 path.lineTo(0.75001740455627441406, 21.694292068481445312);
414 path.lineTo(0.75001740455627441406, 23.051967620849609375);
415 return path;
416 },
417
418 // Reduction from skbug.com/7911 that causes a crash due to splitting a
419 // zombie edge.
420 []() -> SkPath {
421 SkPath path;
422 path.moveTo( 0, 1.0927740941146660348e+24);
423 path.lineTo(2.9333931225865729333e+32, 16476101);
424 path.lineTo(1.0927731573659435417e+24, 1.0927740941146660348e+24);
425 path.lineTo(1.0927740941146660348e+24, 3.7616281094287041715e-37);
426 path.lineTo(1.0927740941146660348e+24, 1.0927740941146660348e+24);
427 path.lineTo(1.3061803026169399536e-33, 1.0927740941146660348e+24);
428 path.lineTo(4.7195362919941370727e-16, -8.4247545146051822591e+32);
429 return path;
430 },
431
432 // From crbug.com/844873. Crashes trying to merge a zombie edge.
433 []() -> SkPath {
434 SkPath path;
435 path.moveTo( 316.000579833984375, -4338355948977389568);
436 path.lineTo(1.5069369808623501312e+20, 75180972320904708096.0);
437 path.lineTo(1.5069369808623501312e+20, 75180972320904708096.0);
438 path.lineTo( 771.21014404296875, -4338355948977389568.0);
439 path.lineTo( 316.000579833984375, -4338355948977389568.0);
440 path.moveTo( 354.208984375, -4338355948977389568.0);
441 path.lineTo( 773.00177001953125, -4338355948977389568.0);
442 path.lineTo(1.5069369808623501312e+20, 75180972320904708096.0);
443 path.lineTo(1.5069369808623501312e+20, 75180972320904708096.0);
444 path.lineTo( 354.208984375, -4338355948977389568.0);
445 return path;
446 },
447
448 // From crbug.com/844873. Hangs repeatedly splitting alternate vertices.
449 []() -> SkPath {
450 SkPath path;
451 path.moveTo(10, -1e+20f);
452 path.lineTo(11, 25000);
453 path.lineTo(10, 25000);
454 path.lineTo(11, 25010);
455 return path;
456 },
457
458 // Reduction from circular_arcs_stroke_and_fill_round GM which
459 // repeatedly splits on the opposite edge from case 34 above.
460 []() -> SkPath {
461 SkPath path;
462 path.moveTo( 16.25, 26.495191574096679688);
463 path.lineTo(32.420825958251953125, 37.377376556396484375);
464 path.lineTo(25.176382064819335938, 39.31851959228515625);
465 path.moveTo( 20, 20);
466 path.lineTo(28.847436904907226562, 37.940830230712890625);
467 path.lineTo(25.17638397216796875, 39.31851959228515625);
468 return path;
469 },
470
471 // Reduction from crbug.com/843135 where an intersection is found
472 // below the bottom of both intersected edges.
473 []() -> SkPath {
474 SkPath path;
475 path.moveTo(-2791476679359332352, 2608107002026524672);
476 path.lineTo( 0, 11.95427703857421875);
477 path.lineTo(-2781824066779086848, 2599088532777598976);
478 path.lineTo( -7772.6875, 7274);
479 return path;
480 },
481
482 // Reduction from crbug.com/843135. Exercises a case where an intersection is missed.
483 // This causes bad ordering in the active edge list.
484 []() -> SkPath {
485 SkPath path;
486 path.moveTo(-1.0662557646016024569e+23, 9.9621425197286319718e+22);
487 path.lineTo( -121806400, 113805032);
488 path.lineTo( -120098872, 112209680);
489 path.lineTo( 6.2832999862817380468e-36, 2.9885697364807128906);
490 return path;
491 },
492
493 // Reduction from crbug.com/851409. Exercises collinear last vertex.
494 []() -> SkPath {
495 SkPath path;
496 path.moveTo(2072553216, 0);
497 path.lineTo(2072553216, 1);
498 path.lineTo(2072553472, -13.5);
499 path.lineTo(2072553216, 0);
500 path.lineTo(2072553472, -6.5);
501 return path;
502 },
503
504 // Another reduction from crbug.com/851409. Exercises two sequential collinear edges.
505 []() -> SkPath {
506 SkPath path;
507 path.moveTo(2072553216, 0);
508 path.lineTo(2072553216, 1);
509 path.lineTo(2072553472, -13);
510 path.lineTo(2072553216, 0);
511 path.lineTo(2072553472, -6);
512 path.lineTo(2072553472, -13);
513 return path;
514 },
515
516 // Reduction from crbug.com/860655. Cause is three collinear edges discovered during
517 // sanitize_contours pass, before the vertices have been found coincident.
518 []() -> SkPath {
519 SkPath path;
520 path.moveTo( 32572426382475264, -3053391034974208);
521 path.lineTo( 521289856, -48865776);
522 path.lineTo( 130322464, -12215873);
523 path.moveTo( 32572426382475264, -3053391034974208);
524 path.lineTo( 521289856, -48865776);
525 path.lineTo( 130322464, -12215873);
526 path.moveTo( 32572426382475264, -3053391034974208);
527 path.lineTo( 32114477642022912, -3010462031544320);
528 path.lineTo( 32111784697528320, -3010209702215680);
529 return path;
530 },
531};