1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkMatrix.h" 9cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 10cb93a386Sopenharmony_ci#include "include/core/SkRRect.h" 11cb93a386Sopenharmony_ci#include "src/core/SkPathPriv.h" 12cb93a386Sopenharmony_ci#include "tests/Test.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cistatic SkRRect path_contains_rrect(skiatest::Reporter* reporter, const SkPath& path, 15cb93a386Sopenharmony_ci SkPathDirection* dir, unsigned* start) { 16cb93a386Sopenharmony_ci SkRRect out; 17cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkPathPriv::IsRRect(path, &out, dir, start)); 18cb93a386Sopenharmony_ci SkPath recreatedPath; 19cb93a386Sopenharmony_ci recreatedPath.addRRect(out, *dir, *start); 20cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, path == recreatedPath); 21cb93a386Sopenharmony_ci // Test that rotations/mirrors of the rrect path are still rrect paths and the returned 22cb93a386Sopenharmony_ci // parameters for the transformed paths are correct. 23cb93a386Sopenharmony_ci static const SkMatrix kMatrices[] = { 24cb93a386Sopenharmony_ci SkMatrix::Scale( 1, 1), 25cb93a386Sopenharmony_ci SkMatrix::Scale(-1, 1), 26cb93a386Sopenharmony_ci SkMatrix::Scale( 1, -1), 27cb93a386Sopenharmony_ci SkMatrix::Scale(-1, -1), 28cb93a386Sopenharmony_ci }; 29cb93a386Sopenharmony_ci for (auto& m : kMatrices) { 30cb93a386Sopenharmony_ci SkPath xformed; 31cb93a386Sopenharmony_ci path.transform(m, &xformed); 32cb93a386Sopenharmony_ci SkRRect xrr = SkRRect::MakeRect(SkRect::MakeEmpty()); 33cb93a386Sopenharmony_ci SkPathDirection xd = SkPathDirection::kCCW; 34cb93a386Sopenharmony_ci unsigned xs = ~0U; 35cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkPathPriv::IsRRect(xformed, &xrr, &xd, &xs)); 36cb93a386Sopenharmony_ci recreatedPath.reset(); 37cb93a386Sopenharmony_ci recreatedPath.addRRect(xrr, xd, xs); 38cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, recreatedPath == xformed); 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci return out; 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_cistatic SkRRect inner_path_contains_rrect(skiatest::Reporter* reporter, const SkRRect& in, 44cb93a386Sopenharmony_ci SkPathDirection dir, unsigned start) { 45cb93a386Sopenharmony_ci switch (in.getType()) { 46cb93a386Sopenharmony_ci case SkRRect::kEmpty_Type: 47cb93a386Sopenharmony_ci case SkRRect::kRect_Type: 48cb93a386Sopenharmony_ci case SkRRect::kOval_Type: 49cb93a386Sopenharmony_ci return in; 50cb93a386Sopenharmony_ci default: 51cb93a386Sopenharmony_ci break; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci SkPath path; 54cb93a386Sopenharmony_ci path.addRRect(in, dir, start); 55cb93a386Sopenharmony_ci SkPathDirection outDir; 56cb93a386Sopenharmony_ci unsigned outStart; 57cb93a386Sopenharmony_ci SkRRect rrect = path_contains_rrect(reporter, path, &outDir, &outStart); 58cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, outDir == dir && outStart == start); 59cb93a386Sopenharmony_ci return rrect; 60cb93a386Sopenharmony_ci} 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_cistatic void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRRect& in, 63cb93a386Sopenharmony_ci SkPathDirection dir, unsigned start) { 64cb93a386Sopenharmony_ci SkRRect out = inner_path_contains_rrect(reporter, in, dir, start); 65cb93a386Sopenharmony_ci if (in != out) { 66cb93a386Sopenharmony_ci SkDebugf("%s", ""); 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, in == out); 69cb93a386Sopenharmony_ci} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_cistatic void path_contains_rrect_nocheck(skiatest::Reporter* reporter, const SkRRect& in, 72cb93a386Sopenharmony_ci SkPathDirection dir, unsigned start) { 73cb93a386Sopenharmony_ci SkRRect out = inner_path_contains_rrect(reporter, in, dir, start); 74cb93a386Sopenharmony_ci if (in == out) { 75cb93a386Sopenharmony_ci SkDebugf("%s", ""); 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci} 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_cistatic void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRect& r, 80cb93a386Sopenharmony_ci SkVector v[4], SkPathDirection dir, unsigned start) { 81cb93a386Sopenharmony_ci SkRRect rrect; 82cb93a386Sopenharmony_ci rrect.setRectRadii(r, v); 83cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rrect, dir, start); 84cb93a386Sopenharmony_ci} 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ciclass ForceIsRRect_Private { 87cb93a386Sopenharmony_cipublic: 88cb93a386Sopenharmony_ci ForceIsRRect_Private(SkPath* path, SkPathDirection dir, unsigned start) { 89cb93a386Sopenharmony_ci path->fPathRef->setIsRRect(true, dir == SkPathDirection::kCCW, start); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci}; 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_cistatic void force_path_contains_rrect(skiatest::Reporter* reporter, SkPath& path, 94cb93a386Sopenharmony_ci SkPathDirection dir, unsigned start) { 95cb93a386Sopenharmony_ci ForceIsRRect_Private force_rrect(&path, dir, start); 96cb93a386Sopenharmony_ci SkPathDirection outDir; 97cb93a386Sopenharmony_ci unsigned outStart; 98cb93a386Sopenharmony_ci path_contains_rrect(reporter, path, &outDir, &outStart); 99cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, outDir == dir && outStart == start); 100cb93a386Sopenharmony_ci} 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_cistatic void test_undetected_paths(skiatest::Reporter* reporter) { 103cb93a386Sopenharmony_ci // We first get the exact conic weight used by SkPath for a circular arc. This 104cb93a386Sopenharmony_ci // allows our local, hand-crafted, artisanal round rect paths below to exactly match the 105cb93a386Sopenharmony_ci // factory made corporate paths produced by SkPath. 106cb93a386Sopenharmony_ci SkPath exactPath; 107cb93a386Sopenharmony_ci exactPath.addCircle(0, 0, 10); 108cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkPath::kMove_Verb == SkPathPriv::VerbData(exactPath)[0]); 109cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkPath::kConic_Verb == SkPathPriv::VerbData(exactPath)[1]); 110cb93a386Sopenharmony_ci const SkScalar weight = SkPathPriv::ConicWeightData(exactPath)[0]; 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci SkPath path; 113cb93a386Sopenharmony_ci path.moveTo(0, 62.5f); 114cb93a386Sopenharmony_ci path.lineTo(0, 3.5f); 115cb93a386Sopenharmony_ci path.conicTo(0, 0, 3.5f, 0, weight); 116cb93a386Sopenharmony_ci path.lineTo(196.5f, 0); 117cb93a386Sopenharmony_ci path.conicTo(200, 0, 200, 3.5f, weight); 118cb93a386Sopenharmony_ci path.lineTo(200, 62.5f); 119cb93a386Sopenharmony_ci path.conicTo(200, 66, 196.5f, 66, weight); 120cb93a386Sopenharmony_ci path.lineTo(3.5f, 66); 121cb93a386Sopenharmony_ci path.conicTo(0, 66, 0, 62.5, weight); 122cb93a386Sopenharmony_ci path.close(); 123cb93a386Sopenharmony_ci force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci path.reset(); 126cb93a386Sopenharmony_ci path.moveTo(0, 81.5f); 127cb93a386Sopenharmony_ci path.lineTo(0, 3.5f); 128cb93a386Sopenharmony_ci path.conicTo(0, 0, 3.5f, 0, weight); 129cb93a386Sopenharmony_ci path.lineTo(149.5, 0); 130cb93a386Sopenharmony_ci path.conicTo(153, 0, 153, 3.5f, weight); 131cb93a386Sopenharmony_ci path.lineTo(153, 81.5f); 132cb93a386Sopenharmony_ci path.conicTo(153, 85, 149.5f, 85, weight); 133cb93a386Sopenharmony_ci path.lineTo(3.5f, 85); 134cb93a386Sopenharmony_ci path.conicTo(0, 85, 0, 81.5f, weight); 135cb93a386Sopenharmony_ci path.close(); 136cb93a386Sopenharmony_ci force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6); 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci path.reset(); 139cb93a386Sopenharmony_ci path.moveTo(14, 1189); 140cb93a386Sopenharmony_ci path.lineTo(14, 21); 141cb93a386Sopenharmony_ci path.conicTo(14, 14, 21, 14, weight); 142cb93a386Sopenharmony_ci path.lineTo(1363, 14); 143cb93a386Sopenharmony_ci path.conicTo(1370, 14, 1370, 21, weight); 144cb93a386Sopenharmony_ci path.lineTo(1370, 1189); 145cb93a386Sopenharmony_ci path.conicTo(1370, 1196, 1363, 1196, weight); 146cb93a386Sopenharmony_ci path.lineTo(21, 1196); 147cb93a386Sopenharmony_ci path.conicTo(14, 1196, 14, 1189, weight); 148cb93a386Sopenharmony_ci path.close(); 149cb93a386Sopenharmony_ci force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6); 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci path.reset(); 152cb93a386Sopenharmony_ci path.moveTo(14, 1743); 153cb93a386Sopenharmony_ci path.lineTo(14, 21); 154cb93a386Sopenharmony_ci path.conicTo(14, 14, 21, 14, weight); 155cb93a386Sopenharmony_ci path.lineTo(1363, 14); 156cb93a386Sopenharmony_ci path.conicTo(1370, 14, 1370, 21, weight); 157cb93a386Sopenharmony_ci path.lineTo(1370, 1743); 158cb93a386Sopenharmony_ci path.conicTo(1370, 1750, 1363, 1750, weight); 159cb93a386Sopenharmony_ci path.lineTo(21, 1750); 160cb93a386Sopenharmony_ci path.conicTo(14, 1750, 14, 1743, weight); 161cb93a386Sopenharmony_ci path.close(); 162cb93a386Sopenharmony_ci force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6); 163cb93a386Sopenharmony_ci} 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_cistatic const SkScalar kWidth = 100.0f; 166cb93a386Sopenharmony_cistatic const SkScalar kHeight = 100.0f; 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_cistatic void test_tricky_radii(skiatest::Reporter* reporter) { 169cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 170cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 171cb93a386Sopenharmony_ci { 172cb93a386Sopenharmony_ci // crbug.com/458522 173cb93a386Sopenharmony_ci SkRRect rr; 174cb93a386Sopenharmony_ci const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; 175cb93a386Sopenharmony_ci const SkScalar rad = 12814; 176cb93a386Sopenharmony_ci const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad }, { 0, rad } }; 177cb93a386Sopenharmony_ci rr.setRectRadii(bounds, vec); 178cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_ci { 182cb93a386Sopenharmony_ci // crbug.com//463920 183cb93a386Sopenharmony_ci SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0); 184cb93a386Sopenharmony_ci SkVector radii[4] = { 185cb93a386Sopenharmony_ci { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, { 110.0f, 5.0f } 186cb93a386Sopenharmony_ci }; 187cb93a386Sopenharmony_ci SkRRect rr; 188cb93a386Sopenharmony_ci rr.setRectRadii(r, radii); 189cb93a386Sopenharmony_ci path_contains_rrect_nocheck(reporter, rr, dir, start); 190cb93a386Sopenharmony_ci } 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci } 193cb93a386Sopenharmony_ci} 194cb93a386Sopenharmony_ci 195cb93a386Sopenharmony_cistatic void test_empty_crbug_458524(skiatest::Reporter* reporter) { 196cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 197cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 198cb93a386Sopenharmony_ci SkRRect rr; 199cb93a386Sopenharmony_ci const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; 200cb93a386Sopenharmony_ci const SkScalar rad = 40; 201cb93a386Sopenharmony_ci rr.setRectXY(bounds, rad, rad); 202cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_ci SkRRect other; 205cb93a386Sopenharmony_ci SkMatrix matrix; 206cb93a386Sopenharmony_ci matrix.setScale(0, 1); 207cb93a386Sopenharmony_ci rr.transform(matrix, &other); 208cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 209cb93a386Sopenharmony_ci } 210cb93a386Sopenharmony_ci } 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_cistatic void test_inset(skiatest::Reporter* reporter) { 214cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 215cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 216cb93a386Sopenharmony_ci SkRRect rr, rr2; 217cb93a386Sopenharmony_ci SkRect r = { 0, 0, 100, 100 }; 218cb93a386Sopenharmony_ci 219cb93a386Sopenharmony_ci rr.setRect(r); 220cb93a386Sopenharmony_ci rr.inset(-20, -20, &rr2); 221cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_ci rr.inset(20, 20, &rr2); 224cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 225cb93a386Sopenharmony_ci 226cb93a386Sopenharmony_ci rr.inset(r.width()/2, r.height()/2, &rr2); 227cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci rr.setRectXY(r, 20, 20); 230cb93a386Sopenharmony_ci rr.inset(19, 19, &rr2); 231cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 232cb93a386Sopenharmony_ci rr.inset(20, 20, &rr2); 233cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 234cb93a386Sopenharmony_ci } 235cb93a386Sopenharmony_ci } 236cb93a386Sopenharmony_ci} 237cb93a386Sopenharmony_ci 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_cistatic void test_9patch_rrect(skiatest::Reporter* reporter, 240cb93a386Sopenharmony_ci const SkRect& rect, 241cb93a386Sopenharmony_ci SkScalar l, SkScalar t, SkScalar r, SkScalar b, 242cb93a386Sopenharmony_ci bool checkRadii) { 243cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 244cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 245cb93a386Sopenharmony_ci SkRRect rr; 246cb93a386Sopenharmony_ci rr.setNinePatch(rect, l, t, r, b); 247cb93a386Sopenharmony_ci if (checkRadii) { 248cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 249cb93a386Sopenharmony_ci } else { 250cb93a386Sopenharmony_ci path_contains_rrect_nocheck(reporter, rr, dir, start); 251cb93a386Sopenharmony_ci } 252cb93a386Sopenharmony_ci 253cb93a386Sopenharmony_ci SkRRect rr2; // construct the same RR using the most general set function 254cb93a386Sopenharmony_ci SkVector radii[4] = { { l, t }, { r, t }, { r, b }, { l, b } }; 255cb93a386Sopenharmony_ci rr2.setRectRadii(rect, radii); 256cb93a386Sopenharmony_ci if (checkRadii) { 257cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 258cb93a386Sopenharmony_ci } else { 259cb93a386Sopenharmony_ci path_contains_rrect_nocheck(reporter, rr, dir, start); 260cb93a386Sopenharmony_ci } 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci } 263cb93a386Sopenharmony_ci} 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ci// Test out the basic API entry points 266cb93a386Sopenharmony_cistatic void test_round_rect_basic(skiatest::Reporter* reporter) { 267cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 268cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 269cb93a386Sopenharmony_ci //---- 270cb93a386Sopenharmony_ci SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_ci SkRRect rr1; 273cb93a386Sopenharmony_ci rr1.setRect(rect); 274cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr1, dir, start); 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci SkRRect rr1_2; // construct the same RR using the most general set function 277cb93a386Sopenharmony_ci SkVector rr1_2_radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; 278cb93a386Sopenharmony_ci rr1_2.setRectRadii(rect, rr1_2_radii); 279cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr1_2, dir, start); 280cb93a386Sopenharmony_ci SkRRect rr1_3; // construct the same RR using the nine patch set function 281cb93a386Sopenharmony_ci rr1_3.setNinePatch(rect, 0, 0, 0, 0); 282cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr1_2, dir, start); 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_ci //---- 285cb93a386Sopenharmony_ci SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) }; 286cb93a386Sopenharmony_ci SkRRect rr2; 287cb93a386Sopenharmony_ci rr2.setOval(rect); 288cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr2, dir, start); 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci SkRRect rr2_2; // construct the same RR using the most general set function 291cb93a386Sopenharmony_ci SkVector rr2_2_radii[4] = { { halfPoint.fX, halfPoint.fY }, 292cb93a386Sopenharmony_ci { halfPoint.fX, halfPoint.fY }, 293cb93a386Sopenharmony_ci { halfPoint.fX, halfPoint.fY }, 294cb93a386Sopenharmony_ci { halfPoint.fX, halfPoint.fY } }; 295cb93a386Sopenharmony_ci rr2_2.setRectRadii(rect, rr2_2_radii); 296cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr2_2, dir, start); 297cb93a386Sopenharmony_ci SkRRect rr2_3; // construct the same RR using the nine patch set function 298cb93a386Sopenharmony_ci rr2_3.setNinePatch(rect, halfPoint.fX, halfPoint.fY, halfPoint.fX, halfPoint.fY); 299cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr2_3, dir, start); 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_ci //---- 302cb93a386Sopenharmony_ci SkPoint p = { 5, 5 }; 303cb93a386Sopenharmony_ci SkRRect rr3; 304cb93a386Sopenharmony_ci rr3.setRectXY(rect, p.fX, p.fY); 305cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr3, dir, start); 306cb93a386Sopenharmony_ci 307cb93a386Sopenharmony_ci SkRRect rr3_2; // construct the same RR using the most general set function 308cb93a386Sopenharmony_ci SkVector rr3_2_radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } }; 309cb93a386Sopenharmony_ci rr3_2.setRectRadii(rect, rr3_2_radii); 310cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr3_2, dir, start); 311cb93a386Sopenharmony_ci SkRRect rr3_3; // construct the same RR using the nine patch set function 312cb93a386Sopenharmony_ci rr3_3.setNinePatch(rect, 5, 5, 5, 5); 313cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr3_3, dir, start); 314cb93a386Sopenharmony_ci 315cb93a386Sopenharmony_ci //---- 316cb93a386Sopenharmony_ci test_9patch_rrect(reporter, rect, 10, 9, 8, 7, true); 317cb93a386Sopenharmony_ci 318cb93a386Sopenharmony_ci { 319cb93a386Sopenharmony_ci // Test out the rrect from skia:3466 320cb93a386Sopenharmony_ci SkRect rect2 = SkRect::MakeLTRB(0.358211994f, 0.755430222f, 0.872866154f, 321cb93a386Sopenharmony_ci 0.806214333f); 322cb93a386Sopenharmony_ci 323cb93a386Sopenharmony_ci test_9patch_rrect(reporter, 324cb93a386Sopenharmony_ci rect2, 325cb93a386Sopenharmony_ci 0.926942348f, 0.642850280f, 0.529063463f, 0.587844372f, 326cb93a386Sopenharmony_ci false); 327cb93a386Sopenharmony_ci } 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci //---- 330cb93a386Sopenharmony_ci SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } }; 331cb93a386Sopenharmony_ci 332cb93a386Sopenharmony_ci SkRRect rr5; 333cb93a386Sopenharmony_ci rr5.setRectRadii(rect, radii2); 334cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr5, dir, start); 335cb93a386Sopenharmony_ci } 336cb93a386Sopenharmony_ci } 337cb93a386Sopenharmony_ci} 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci// Test out the cases when the RR degenerates to a rect 340cb93a386Sopenharmony_cistatic void test_round_rect_rects(skiatest::Reporter* reporter) { 341cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 342cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 343cb93a386Sopenharmony_ci //---- 344cb93a386Sopenharmony_ci SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); 345cb93a386Sopenharmony_ci SkRRect rr1; 346cb93a386Sopenharmony_ci rr1.setRectXY(rect, 0, 0); 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr1, dir, start); 349cb93a386Sopenharmony_ci 350cb93a386Sopenharmony_ci //---- 351cb93a386Sopenharmony_ci SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; 352cb93a386Sopenharmony_ci 353cb93a386Sopenharmony_ci SkRRect rr2; 354cb93a386Sopenharmony_ci rr2.setRectRadii(rect, radii); 355cb93a386Sopenharmony_ci 356cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr2, dir, start); 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ci //---- 359cb93a386Sopenharmony_ci SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; 360cb93a386Sopenharmony_ci 361cb93a386Sopenharmony_ci SkRRect rr3; 362cb93a386Sopenharmony_ci rr3.setRectRadii(rect, radii2); 363cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr3, dir, start); 364cb93a386Sopenharmony_ci } 365cb93a386Sopenharmony_ci } 366cb93a386Sopenharmony_ci} 367cb93a386Sopenharmony_ci 368cb93a386Sopenharmony_ci// Test out the cases when the RR degenerates to an oval 369cb93a386Sopenharmony_cistatic void test_round_rect_ovals(skiatest::Reporter* reporter) { 370cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 371cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 372cb93a386Sopenharmony_ci //---- 373cb93a386Sopenharmony_ci SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); 374cb93a386Sopenharmony_ci SkRRect rr1; 375cb93a386Sopenharmony_ci rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight)); 376cb93a386Sopenharmony_ci 377cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr1, dir, start); 378cb93a386Sopenharmony_ci } 379cb93a386Sopenharmony_ci } 380cb93a386Sopenharmony_ci} 381cb93a386Sopenharmony_ci 382cb93a386Sopenharmony_ci// Test out the non-degenerate RR cases 383cb93a386Sopenharmony_cistatic void test_round_rect_general(skiatest::Reporter* reporter) { 384cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 385cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 386cb93a386Sopenharmony_ci //---- 387cb93a386Sopenharmony_ci SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); 388cb93a386Sopenharmony_ci SkRRect rr1; 389cb93a386Sopenharmony_ci rr1.setRectXY(rect, 20, 20); 390cb93a386Sopenharmony_ci 391cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr1, dir, start); 392cb93a386Sopenharmony_ci 393cb93a386Sopenharmony_ci //---- 394cb93a386Sopenharmony_ci SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; 395cb93a386Sopenharmony_ci 396cb93a386Sopenharmony_ci SkRRect rr2; 397cb93a386Sopenharmony_ci rr2.setRectRadii(rect, radii); 398cb93a386Sopenharmony_ci 399cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr2, dir, start); 400cb93a386Sopenharmony_ci } 401cb93a386Sopenharmony_ci } 402cb93a386Sopenharmony_ci} 403cb93a386Sopenharmony_ci 404cb93a386Sopenharmony_cistatic void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) { 405cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 406cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 407cb93a386Sopenharmony_ci SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); 408cb93a386Sopenharmony_ci SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } }; 409cb93a386Sopenharmony_ci SkRRect rr1; 410cb93a386Sopenharmony_ci rr1.setRectRadii(rect, radii); 411cb93a386Sopenharmony_ci path_contains_rrect_nocheck(reporter, rr1, dir, start); 412cb93a386Sopenharmony_ci } 413cb93a386Sopenharmony_ci } 414cb93a386Sopenharmony_ci} 415cb93a386Sopenharmony_ci 416cb93a386Sopenharmony_cistatic void set_radii(SkVector radii[4], int index, float rad) { 417cb93a386Sopenharmony_ci sk_bzero(radii, sizeof(SkVector) * 4); 418cb93a386Sopenharmony_ci radii[index].set(rad, rad); 419cb93a386Sopenharmony_ci} 420cb93a386Sopenharmony_ci 421cb93a386Sopenharmony_cistatic void test_skbug_3239(skiatest::Reporter* reporter) { 422cb93a386Sopenharmony_ci const float min = SkBits2Float(0xcb7f16c8); /* -16717512.000000 */ 423cb93a386Sopenharmony_ci const float max = SkBits2Float(0x4b7f1c1d); /* 16718877.000000 */ 424cb93a386Sopenharmony_ci const float big = SkBits2Float(0x4b7f1bd7); /* 16718807.000000 */ 425cb93a386Sopenharmony_ci 426cb93a386Sopenharmony_ci const float rad = 33436320; 427cb93a386Sopenharmony_ci 428cb93a386Sopenharmony_ci const SkRect rectx = SkRect::MakeLTRB(min, min, max, big); 429cb93a386Sopenharmony_ci const SkRect recty = SkRect::MakeLTRB(min, min, big, max); 430cb93a386Sopenharmony_ci 431cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 432cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 433cb93a386Sopenharmony_ci SkVector radii[4]; 434cb93a386Sopenharmony_ci for (int i = 0; i < 4; ++i) { 435cb93a386Sopenharmony_ci set_radii(radii, i, rad); 436cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rectx, radii, dir, start); 437cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, recty, radii, dir, start); 438cb93a386Sopenharmony_ci } 439cb93a386Sopenharmony_ci } 440cb93a386Sopenharmony_ci } 441cb93a386Sopenharmony_ci} 442cb93a386Sopenharmony_ci 443cb93a386Sopenharmony_cistatic void test_mix(skiatest::Reporter* reporter) { 444cb93a386Sopenharmony_ci for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) { 445cb93a386Sopenharmony_ci for (int start = 0; start < 8; ++start) { 446cb93a386Sopenharmony_ci // Test out mixed degenerate and non-degenerate geometry with Conics 447cb93a386Sopenharmony_ci const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } }; 448cb93a386Sopenharmony_ci SkRect r = SkRect::MakeWH(100, 100); 449cb93a386Sopenharmony_ci SkRRect rr; 450cb93a386Sopenharmony_ci rr.setRectRadii(r, radii); 451cb93a386Sopenharmony_ci path_contains_rrect_check(reporter, rr, dir, start); 452cb93a386Sopenharmony_ci } 453cb93a386Sopenharmony_ci } 454cb93a386Sopenharmony_ci} 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ciDEF_TEST(RoundRectInPath, reporter) { 457cb93a386Sopenharmony_ci test_tricky_radii(reporter); 458cb93a386Sopenharmony_ci test_empty_crbug_458524(reporter); 459cb93a386Sopenharmony_ci test_inset(reporter); 460cb93a386Sopenharmony_ci test_round_rect_basic(reporter); 461cb93a386Sopenharmony_ci test_round_rect_rects(reporter); 462cb93a386Sopenharmony_ci test_round_rect_ovals(reporter); 463cb93a386Sopenharmony_ci test_round_rect_general(reporter); 464cb93a386Sopenharmony_ci test_undetected_paths(reporter); 465cb93a386Sopenharmony_ci test_round_rect_iffy_parameters(reporter); 466cb93a386Sopenharmony_ci test_skbug_3239(reporter); 467cb93a386Sopenharmony_ci test_mix(reporter); 468cb93a386Sopenharmony_ci} 469cb93a386Sopenharmony_ci 470cb93a386Sopenharmony_ciDEF_TEST(RRect_fragile, reporter) { 471cb93a386Sopenharmony_ci SkRect rect = { 472cb93a386Sopenharmony_ci SkBits2Float(0x1f800000), // 0x003F0000 was the starter value that also fails 473cb93a386Sopenharmony_ci SkBits2Float(0x1400001C), 474cb93a386Sopenharmony_ci SkBits2Float(0x3F000004), 475cb93a386Sopenharmony_ci SkBits2Float(0x3F000004), 476cb93a386Sopenharmony_ci }; 477cb93a386Sopenharmony_ci 478cb93a386Sopenharmony_ci SkPoint radii[] = { 479cb93a386Sopenharmony_ci { SkBits2Float(0x00000001), SkBits2Float(0x00000001) }, 480cb93a386Sopenharmony_ci { SkBits2Float(0x00000020), SkBits2Float(0x00000001) }, 481cb93a386Sopenharmony_ci { SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, 482cb93a386Sopenharmony_ci { SkBits2Float(0x3F000004), SkBits2Float(0x3F000004) }, 483cb93a386Sopenharmony_ci }; 484cb93a386Sopenharmony_ci 485cb93a386Sopenharmony_ci SkRRect rr; 486cb93a386Sopenharmony_ci // please don't assert 487cb93a386Sopenharmony_ci if (false) { // disable until we fix this 488cb93a386Sopenharmony_ci SkDebugf("%g 0x%08X\n", rect.fLeft, SkFloat2Bits(rect.fLeft)); 489cb93a386Sopenharmony_ci rr.setRectRadii(rect, radii); 490cb93a386Sopenharmony_ci } 491cb93a386Sopenharmony_ci} 492cb93a386Sopenharmony_ci 493