1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 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/utils/SkParsePath.h" 9cb93a386Sopenharmony_ci#include "tests/Test.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_cistatic void test_to_from(skiatest::Reporter* reporter, const SkPath& path) { 12cb93a386Sopenharmony_ci SkString str, str2; 13cb93a386Sopenharmony_ci SkParsePath::ToSVGString(path, &str); 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci SkPath path2; 16cb93a386Sopenharmony_ci bool success = SkParsePath::FromSVGString(str.c_str(), &path2); 17cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, success); 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci SkParsePath::ToSVGString(path2, &str2); 20cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, str == str2); 21cb93a386Sopenharmony_ci#if 0 // closed paths are not equal, the iter explicitly gives the closing 22cb93a386Sopenharmony_ci // edge, even if it is not in the path. 23cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, path == path2); 24cb93a386Sopenharmony_ci if (path != path2) { 25cb93a386Sopenharmony_ci SkDebugf("str1=%s\nstr2=%s\n", str.c_str(), str2.c_str()); 26cb93a386Sopenharmony_ci } 27cb93a386Sopenharmony_ci#endif 28cb93a386Sopenharmony_ci} 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_cistatic struct { 31cb93a386Sopenharmony_ci const char* fStr; 32cb93a386Sopenharmony_ci const SkRect fBounds; 33cb93a386Sopenharmony_ci} gRec[] = { 34cb93a386Sopenharmony_ci { "M1,1 l-2.58-2.828-3.82-0.113, 1.9-3.3223-1.08-3.6702, 3.75,0.7744,3.16-2.1551," 35cb93a386Sopenharmony_ci "0.42,3.8008,3.02,2.3384-3.48,1.574-1.29,3.601z", 36cb93a386Sopenharmony_ci { -5.39999962f, -10.3142f, 5.77000046f, 1.f } }, 37cb93a386Sopenharmony_ci { "", { 0, 0, 0, 0 } }, 38cb93a386Sopenharmony_ci { "M0,0L10,10", { 0, 0, SkIntToScalar(10), SkIntToScalar(10) } }, 39cb93a386Sopenharmony_ci { "M-5.5,-0.5 Q 0 0 6,6.50", 40cb93a386Sopenharmony_ci { -5.5f, -0.5f, 41cb93a386Sopenharmony_ci 6, 6.5f } } 42cb93a386Sopenharmony_ci}; 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ciDEF_TEST(ParsePath, reporter) { 45cb93a386Sopenharmony_ci for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { 46cb93a386Sopenharmony_ci SkPath path; 47cb93a386Sopenharmony_ci bool success = SkParsePath::FromSVGString(gRec[i].fStr, &path); 48cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, success); 49cb93a386Sopenharmony_ci const SkRect& expectedBounds = gRec[i].fBounds; 50cb93a386Sopenharmony_ci const SkRect& pathBounds = path.getBounds(); 51cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, expectedBounds == pathBounds); 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci test_to_from(reporter, path); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci SkRect r; 57cb93a386Sopenharmony_ci r.setLTRB(0, 0, 10, 10.5f); 58cb93a386Sopenharmony_ci SkPath p; 59cb93a386Sopenharmony_ci p.addRect(r); 60cb93a386Sopenharmony_ci test_to_from(reporter, p); 61cb93a386Sopenharmony_ci p.addOval(r); 62cb93a386Sopenharmony_ci test_to_from(reporter, p); 63cb93a386Sopenharmony_ci p.addRoundRect(r, 4, 4.5f); 64cb93a386Sopenharmony_ci test_to_from(reporter, p); 65cb93a386Sopenharmony_ci} 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ciDEF_TEST(ParsePath_invalid, r) { 68cb93a386Sopenharmony_ci SkPath path; 69cb93a386Sopenharmony_ci // This is an invalid SVG string, but the test verifies that we do not 70cb93a386Sopenharmony_ci // crash. 71cb93a386Sopenharmony_ci bool success = SkParsePath::FromSVGString("M 5", &path); 72cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !success); 73cb93a386Sopenharmony_ci} 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 76cb93a386Sopenharmony_ci#include "tools/random_parse_path.h" 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ciDEF_TEST(ParsePathRandom, r) { 79cb93a386Sopenharmony_ci SkRandom rand; 80cb93a386Sopenharmony_ci for (int index = 0; index < 1000; ++index) { 81cb93a386Sopenharmony_ci SkPath path, path2; 82cb93a386Sopenharmony_ci SkString spec; 83cb93a386Sopenharmony_ci uint32_t count = rand.nextRangeU(0, 10); 84cb93a386Sopenharmony_ci for (uint32_t i = 0; i < count; ++i) { 85cb93a386Sopenharmony_ci spec.append(MakeRandomParsePathPiece(&rand)); 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci bool success = SkParsePath::FromSVGString(spec.c_str(), &path); 88cb93a386Sopenharmony_ci REPORTER_ASSERT(r, success); 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciDEF_TEST(ParsePathOptionalCommand, r) { 93cb93a386Sopenharmony_ci struct { 94cb93a386Sopenharmony_ci const char* fStr; 95cb93a386Sopenharmony_ci int fVerbs; 96cb93a386Sopenharmony_ci int fPoints; 97cb93a386Sopenharmony_ci } gTests[] = { 98cb93a386Sopenharmony_ci { "", 0, 0 }, 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci { "H100 200 ", 3, 3 }, 101cb93a386Sopenharmony_ci { "H-100-200", 3, 3 }, 102cb93a386Sopenharmony_ci { "H+100+200", 3, 3 }, 103cb93a386Sopenharmony_ci { "H.10.20" , 3, 3 }, 104cb93a386Sopenharmony_ci { "H-.10-.20", 3, 3 }, 105cb93a386Sopenharmony_ci { "H+.10+.20", 3, 3 }, 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci { "L100 100 200 200" , 3, 3 }, 108cb93a386Sopenharmony_ci { "L-100-100-200-200", 3, 3 }, 109cb93a386Sopenharmony_ci { "L+100+100+200+200", 3, 3 }, 110cb93a386Sopenharmony_ci { "L.10.10.20.20" , 3, 3 }, 111cb93a386Sopenharmony_ci { "L-.10-.10-.20-.20", 3, 3 }, 112cb93a386Sopenharmony_ci { "L+.10+.10+.20+.20", 3, 3 }, 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci { "C100 100 200 200 300 300 400 400 500 500 600 600" , 3, 7 }, 115cb93a386Sopenharmony_ci { "C100-100-200-200-300-300-400-400-500-500-600-600" , 3, 7 }, 116cb93a386Sopenharmony_ci { "C100+100+200+200+300+300+400+400+500+500+600+600" , 3, 7 }, 117cb93a386Sopenharmony_ci { "C.10.10.20.20.30.30.40.40.50.50.60.60" , 3, 7 }, 118cb93a386Sopenharmony_ci { "C-.10-.10-.20-.20-.30-.30-.40-.40-.50-.50-.60-.60", 3, 7 }, 119cb93a386Sopenharmony_ci { "C+.10+.10+.20+.20+.30+.30+.40+.40+.50+.50+.60+.60", 3, 7 }, 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci { "c-1.49.71-2.12 2.5-1.4 4 .71 1.49 2.5 2.12 4 1.4z", 4, 7 }, 122cb93a386Sopenharmony_ci }; 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci SkPath path; 125cb93a386Sopenharmony_ci for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) { 126cb93a386Sopenharmony_ci REPORTER_ASSERT(r, SkParsePath::FromSVGString(gTests[i].fStr, &path)); 127cb93a386Sopenharmony_ci REPORTER_ASSERT(r, path.countVerbs() == gTests[i].fVerbs); 128cb93a386Sopenharmony_ci REPORTER_ASSERT(r, path.countPoints() == gTests[i].fPoints); 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci} 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ciDEF_TEST(ParsePathArcFlags, r) { 133cb93a386Sopenharmony_ci const char* arcs = "M10 10a2.143 2.143 0 100-4.285 2.143 2.143 0 000 4.286"; 134cb93a386Sopenharmony_ci SkPath path; 135cb93a386Sopenharmony_ci REPORTER_ASSERT(r, SkParsePath::FromSVGString(arcs, &path)); 136cb93a386Sopenharmony_ci // Arcs decompose to two conics. 137cb93a386Sopenharmony_ci REPORTER_ASSERT(r, path.countVerbs() == 5); 138cb93a386Sopenharmony_ci // One for move, 2x per conic. 139cb93a386Sopenharmony_ci REPORTER_ASSERT(r, path.countPoints() == 9); 140cb93a386Sopenharmony_ci}