Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: tests/PathTest.cpp

Issue 2017743002: Fix bug where SkPath will convert an arc to an oval and change the starting point. (Closed) Base URL: https://chromium.googlesource.com/skia.git@dirandstart
Patch Set: Address comments, improve test, fix implementation Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkPath.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include <cmath>
8 #include "SkCanvas.h" 9 #include "SkCanvas.h"
9 #include "SkGeometry.h" 10 #include "SkGeometry.h"
10 #include "SkPaint.h" 11 #include "SkPaint.h"
11 #include "SkParse.h" 12 #include "SkParse.h"
12 #include "SkParsePath.h" 13 #include "SkParsePath.h"
13 #include "SkPathPriv.h" 14 #include "SkPathPriv.h"
14 #include "SkPathEffect.h" 15 #include "SkPathEffect.h"
15 #include "SkRRect.h" 16 #include "SkRRect.h"
16 #include "SkRandom.h" 17 #include "SkRandom.h"
17 #include "SkReader32.h" 18 #include "SkReader32.h"
(...skipping 3281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3299 REPORTER_ASSERT(reporter, emptyOval.isEmpty()); 3300 REPORTER_ASSERT(reporter, emptyOval.isEmpty());
3300 p.addArc(emptyOval, 1, 2); 3301 p.addArc(emptyOval, 1, 2);
3301 REPORTER_ASSERT(reporter, p.isEmpty()); 3302 REPORTER_ASSERT(reporter, p.isEmpty());
3302 p.reset(); 3303 p.reset();
3303 SkRect oval = {10, 20, 30, 40}; 3304 SkRect oval = {10, 20, 30, 40};
3304 p.addArc(oval, 1, 0); 3305 p.addArc(oval, 1, 0);
3305 REPORTER_ASSERT(reporter, p.isEmpty()); 3306 REPORTER_ASSERT(reporter, p.isEmpty());
3306 p.reset(); 3307 p.reset();
3307 SkPath cwOval; 3308 SkPath cwOval;
3308 cwOval.addOval(oval); 3309 cwOval.addOval(oval);
3309 p.addArc(oval, 1, 360); 3310 p.addArc(oval, 0, 360);
3310 REPORTER_ASSERT(reporter, p == cwOval); 3311 REPORTER_ASSERT(reporter, p == cwOval);
3311 p.reset(); 3312 p.reset();
3312 SkPath ccwOval; 3313 SkPath ccwOval;
3313 ccwOval.addOval(oval, SkPath::kCCW_Direction); 3314 ccwOval.addOval(oval, SkPath::kCCW_Direction);
3314 p.addArc(oval, 1, -360); 3315 p.addArc(oval, 0, -360);
3315 REPORTER_ASSERT(reporter, p == ccwOval); 3316 REPORTER_ASSERT(reporter, p == ccwOval);
3316 p.reset(); 3317 p.reset();
3317 p.addArc(oval, 1, 180); 3318 p.addArc(oval, 1, 180);
3318 REPORTER_ASSERT(reporter, p.isConvex()); 3319 REPORTER_ASSERT(reporter, p.isConvex());
3319 REPORTER_ASSERT(reporter, SkPathPriv::CheapIsFirstDirection(p, SkPathPriv::k CW_FirstDirection)); 3320 REPORTER_ASSERT(reporter, SkPathPriv::CheapIsFirstDirection(p, SkPathPriv::k CW_FirstDirection));
3320 p.setConvexity(SkPath::kUnknown_Convexity); 3321 p.setConvexity(SkPath::kUnknown_Convexity);
3321 REPORTER_ASSERT(reporter, p.isConvex()); 3322 REPORTER_ASSERT(reporter, p.isConvex());
3322 } 3323 }
3323 3324
3325 static inline SkScalar oval_start_index_to_angle(unsigned start) {
3326 switch (start) {
3327 case 0:
3328 return 270.f;
3329 case 1:
3330 return 0.f;
3331 case 2:
3332 return 90.f;
3333 case 3:
3334 return 180.f;
3335 default:
3336 return -1.f;
3337 }
3338 }
3339
3340 static inline SkScalar canonical_start_angle(float angle) {
3341 while (angle < 0.f) {
3342 angle += 360.f;
3343 }
3344 while (angle >= 360.f) {
3345 angle -= 360.f;
3346 }
3347 return angle;
3348 }
3349
3350 static void test_arc_ovals(skiatest::Reporter* reporter) {
3351 SkRect oval = SkRect::MakeWH(10, 20);
3352 for (SkScalar sweep : {-720.f, -540.f, -360.f, 360.f, 432.f, 720.f}) {
3353 for (SkScalar start = -360.f; start <= 360.f; start += 1.f) {
3354 SkPath path;
3355 path.addArc(oval, start, sweep);
3356 SkRect r = SkRect::MakeEmpty();
3357 SkPath::Direction d = SkPath::kCCW_Direction;
3358 unsigned s = ~0U;
3359 bool isOval = path.isOval(&r, &d, &s);
3360 // SkPath's interfaces for inserting and extracting ovals only allow contours
3361 // to start at multiples of 90 degrees.
3362 if (std::fmod(start, 90.f) == 0) {
3363 REPORTER_ASSERT(reporter, isOval);
3364 SkPath recreatedPath;
3365 recreatedPath.addOval(r, d, s);
3366 REPORTER_ASSERT(reporter, path == recreatedPath);
3367 REPORTER_ASSERT(reporter, oval_start_index_to_angle(s) ==
3368 canonical_start_angle(start));
3369 REPORTER_ASSERT(reporter, (SkPath::kCW_Direction == d) ==
3370 (sweep > 0.f));
3371 } else {
3372 REPORTER_ASSERT(reporter, !isOval);
3373 }
3374 }
3375 // Test start angles that are nearly at valid oval start angles.
3376 for (float start : {-180.f, -90.f, 90.f, 180.f}) {
3377 for (float delta : {-SK_ScalarNearlyZero, SK_ScalarNearlyZero}) {
robertphillips 2016/05/27 15:24:59 Can we have a shared check_oval helper that takes
bsalomon 2016/06/10 15:04:33 Done.
3378 SkPath path;
3379 path.addArc(oval, start + delta, sweep);
3380 SkRect r = SkRect::MakeEmpty();
3381 SkPath::Direction d = SkPath::kCCW_Direction;
3382 unsigned s = ~0U;
3383 bool isOval = path.isOval(&r, &d, &s);
3384 REPORTER_ASSERT(reporter, isOval);
3385 SkPath recreatedPath;
3386 recreatedPath.addOval(r, d, s);
3387 REPORTER_ASSERT(reporter, path == recreatedPath);
3388 REPORTER_ASSERT(reporter, oval_start_index_to_angle(s) ==
3389 canonical_start_angle(start));
3390 REPORTER_ASSERT(reporter, (SkPath::kCW_Direction == d) ==
3391 (sweep > 0.f));
3392 }
3393 }
3394 }
3395 }
3396
3324 static void check_move(skiatest::Reporter* reporter, SkPath::RawIter* iter, 3397 static void check_move(skiatest::Reporter* reporter, SkPath::RawIter* iter,
3325 SkScalar x0, SkScalar y0) { 3398 SkScalar x0, SkScalar y0) {
3326 SkPoint pts[4]; 3399 SkPoint pts[4];
3327 SkPath::Verb v = iter->next(pts); 3400 SkPath::Verb v = iter->next(pts);
3328 REPORTER_ASSERT(reporter, v == SkPath::kMove_Verb); 3401 REPORTER_ASSERT(reporter, v == SkPath::kMove_Verb);
3329 REPORTER_ASSERT(reporter, pts[0].fX == x0); 3402 REPORTER_ASSERT(reporter, pts[0].fX == x0);
3330 REPORTER_ASSERT(reporter, pts[0].fY == y0); 3403 REPORTER_ASSERT(reporter, pts[0].fY == y0);
3331 } 3404 }
3332 3405
3333 static void check_line(skiatest::Reporter* reporter, SkPath::RawIter* iter, 3406 static void check_line(skiatest::Reporter* reporter, SkPath::RawIter* iter,
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
4114 test_crbug_170666(); 4187 test_crbug_170666();
4115 test_crbug_493450(reporter); 4188 test_crbug_493450(reporter);
4116 test_crbug_495894(reporter); 4189 test_crbug_495894(reporter);
4117 test_bad_cubic_crbug229478(); 4190 test_bad_cubic_crbug229478();
4118 test_bad_cubic_crbug234190(); 4191 test_bad_cubic_crbug234190();
4119 test_gen_id(reporter); 4192 test_gen_id(reporter);
4120 test_path_close_issue1474(reporter); 4193 test_path_close_issue1474(reporter);
4121 test_path_to_region(reporter); 4194 test_path_to_region(reporter);
4122 test_rrect(reporter); 4195 test_rrect(reporter);
4123 test_arc(reporter); 4196 test_arc(reporter);
4197 test_arc_ovals(reporter);
4124 test_arcTo(reporter); 4198 test_arcTo(reporter);
4125 test_addPath(reporter); 4199 test_addPath(reporter);
4126 test_addPathMode(reporter, false, false); 4200 test_addPathMode(reporter, false, false);
4127 test_addPathMode(reporter, true, false); 4201 test_addPathMode(reporter, true, false);
4128 test_addPathMode(reporter, false, true); 4202 test_addPathMode(reporter, false, true);
4129 test_addPathMode(reporter, true, true); 4203 test_addPathMode(reporter, true, true);
4130 test_extendClosedPath(reporter); 4204 test_extendClosedPath(reporter);
4131 test_addEmptyPath(reporter, SkPath::kExtend_AddPathMode); 4205 test_addEmptyPath(reporter, SkPath::kExtend_AddPathMode);
4132 test_addEmptyPath(reporter, SkPath::kAppend_AddPathMode); 4206 test_addEmptyPath(reporter, SkPath::kAppend_AddPathMode);
4133 test_conicTo_special_case(reporter); 4207 test_conicTo_special_case(reporter);
4134 test_get_point(reporter); 4208 test_get_point(reporter);
4135 test_contains(reporter); 4209 test_contains(reporter);
4136 PathTest_Private::TestPathTo(reporter); 4210 PathTest_Private::TestPathTo(reporter);
4137 PathRefTest_Private::TestPathRef(reporter); 4211 PathRefTest_Private::TestPathRef(reporter);
4138 PathTest_Private::TestPathrefListeners(reporter); 4212 PathTest_Private::TestPathrefListeners(reporter);
4139 test_dump(reporter); 4213 test_dump(reporter);
4140 test_path_crbug389050(reporter); 4214 test_path_crbug389050(reporter);
4141 test_path_crbugskia2820(reporter); 4215 test_path_crbugskia2820(reporter);
4142 test_skbug_3469(reporter); 4216 test_skbug_3469(reporter);
4143 test_skbug_3239(reporter); 4217 test_skbug_3239(reporter);
4144 test_bounds_crbug_513799(reporter); 4218 test_bounds_crbug_513799(reporter);
4145 } 4219 }
OLDNEW
« no previous file with comments | « src/core/SkPath.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698