commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2013 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "include/core/SkTypes.h" |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 9 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 10 | #include "include/core/SkBitmap.h" |
| 11 | #include "include/core/SkCanvas.h" |
| 12 | #include "include/core/SkColor.h" |
| 13 | #include "include/core/SkPaint.h" |
| 14 | #include "include/core/SkPath.h" |
| 15 | #include "include/core/SkRRect.h" |
| 16 | #include "include/core/SkRect.h" |
| 17 | #include "include/core/SkSurface.h" |
| 18 | #include "include/effects/SkDashPathEffect.h" |
Robert Phillips | 6d344c3 | 2020-07-06 10:56:46 -0400 | [diff] [blame] | 19 | #include "include/gpu/GrDirectContext.h" |
Michael Ludwig | 2686d69 | 2020-04-17 20:21:37 +0000 | [diff] [blame] | 20 | #include "src/gpu/geometry/GrStyledShape.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 21 | #include "tests/Test.h" |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 22 | |
kkinnunen | 1530283 | 2015-12-01 04:35:26 -0800 | [diff] [blame] | 23 | #include <initializer_list> |
| 24 | |
tfarina@chromium.org | 4ee16bf | 2014-01-10 22:08:27 +0000 | [diff] [blame] | 25 | static void test_drawPathEmpty(skiatest::Reporter*, SkCanvas* canvas) { |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 26 | // Filling an empty path should not crash. |
| 27 | SkPaint paint; |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 28 | SkRect emptyRect = SkRect::MakeEmpty(); |
| 29 | canvas->drawRect(emptyRect, paint); |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 30 | canvas->drawPath(SkPath(), paint); |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 31 | canvas->drawOval(emptyRect, paint); |
| 32 | canvas->drawRect(emptyRect, paint); |
| 33 | canvas->drawRRect(SkRRect::MakeRect(emptyRect), paint); |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 34 | |
| 35 | // Stroking an empty path should not crash. |
| 36 | paint.setAntiAlias(true); |
| 37 | paint.setStyle(SkPaint::kStroke_Style); |
| 38 | paint.setColor(SK_ColorGRAY); |
| 39 | paint.setStrokeWidth(SkIntToScalar(20)); |
| 40 | paint.setStrokeJoin(SkPaint::kRound_Join); |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 41 | canvas->drawRect(emptyRect, paint); |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 42 | canvas->drawPath(SkPath(), paint); |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 43 | canvas->drawOval(emptyRect, paint); |
| 44 | canvas->drawRect(emptyRect, paint); |
| 45 | canvas->drawRRect(SkRRect::MakeRect(emptyRect), paint); |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 46 | } |
| 47 | |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 48 | static void fill_and_stroke(SkCanvas* canvas, const SkPath& p1, const SkPath& p2, |
reed | a439334 | 2016-03-18 11:22:57 -0700 | [diff] [blame] | 49 | sk_sp<SkPathEffect> effect) { |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 50 | SkPaint paint; |
| 51 | paint.setAntiAlias(true); |
| 52 | paint.setPathEffect(effect); |
| 53 | |
| 54 | canvas->drawPath(p1, paint); |
| 55 | canvas->drawPath(p2, paint); |
| 56 | |
| 57 | paint.setStyle(SkPaint::kStroke_Style); |
| 58 | canvas->drawPath(p1, paint); |
| 59 | canvas->drawPath(p2, paint); |
| 60 | } |
| 61 | |
| 62 | static void test_drawSameRectOvals(skiatest::Reporter*, SkCanvas* canvas) { |
| 63 | // Drawing ovals with similar bounds but different points order should not crash. |
| 64 | |
| 65 | SkPath oval1, oval2; |
| 66 | const SkRect rect = SkRect::MakeWH(100, 50); |
Mike Reed | 30bc527 | 2019-11-22 18:34:02 +0000 | [diff] [blame] | 67 | oval1.addOval(rect, SkPathDirection::kCW); |
| 68 | oval2.addOval(rect, SkPathDirection::kCCW); |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 69 | |
| 70 | fill_and_stroke(canvas, oval1, oval2, nullptr); |
| 71 | |
| 72 | const SkScalar intervals[] = { 1, 1 }; |
reed | a439334 | 2016-03-18 11:22:57 -0700 | [diff] [blame] | 73 | fill_and_stroke(canvas, oval1, oval2, SkDashPathEffect::Make(intervals, 2, 0)); |
fmalita | fbe1c11 | 2015-11-18 20:12:56 -0800 | [diff] [blame] | 74 | } |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 75 | |
bsalomon | 758586c | 2016-04-06 14:02:39 -0700 | [diff] [blame] | 76 | DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GpuDrawPath, reporter, ctxInfo) { |
kkinnunen | 1530283 | 2015-12-01 04:35:26 -0800 | [diff] [blame] | 77 | for (auto& test_func : { &test_drawPathEmpty, &test_drawSameRectOvals }) { |
Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 78 | for (auto& sampleCount : {1, 4, 16}) { |
reed | 69f6f00 | 2014-09-18 06:09:44 -0700 | [diff] [blame] | 79 | SkImageInfo info = SkImageInfo::MakeN32Premul(255, 255); |
reed | e8f3062 | 2016-03-23 18:59:25 -0700 | [diff] [blame] | 80 | auto surface( |
Robert Phillips | 6d344c3 | 2020-07-06 10:56:46 -0400 | [diff] [blame] | 81 | SkSurface::MakeRenderTarget(ctxInfo.directContext(), SkBudgeted::kNo, info, |
bsalomon | 8b7451a | 2016-05-11 06:33:06 -0700 | [diff] [blame] | 82 | sampleCount, nullptr)); |
kkinnunen | c11a527 | 2015-11-19 09:37:02 -0800 | [diff] [blame] | 83 | if (!surface) { |
| 84 | continue; |
| 85 | } |
kkinnunen | 1530283 | 2015-12-01 04:35:26 -0800 | [diff] [blame] | 86 | test_func(reporter, surface->getCanvas()); |
commit-bot@chromium.org | 19dd017 | 2013-08-05 13:28:55 +0000 | [diff] [blame] | 87 | } |
| 88 | } |
| 89 | } |
| 90 | |
Brian Osman | 2caecd2 | 2019-09-25 14:02:26 -0400 | [diff] [blame] | 91 | DEF_GPUTEST_FOR_ALL_CONTEXTS(GrDrawCollapsedPath, reporter, ctxInfo) { |
| 92 | // From https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=37330, it's possible for a convex |
| 93 | // path to be accepted by AAConvexPathRenderer, then be transformed to something without a |
| 94 | // computable first direction by a perspective matrix. |
| 95 | SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); |
Robert Phillips | 6d344c3 | 2020-07-06 10:56:46 -0400 | [diff] [blame] | 96 | auto surface(SkSurface::MakeRenderTarget(ctxInfo.directContext(), SkBudgeted::kNo, info)); |
Brian Osman | 2caecd2 | 2019-09-25 14:02:26 -0400 | [diff] [blame] | 97 | |
| 98 | SkPaint paint; |
| 99 | paint.setAntiAlias(true); |
| 100 | |
| 101 | SkPath path; |
| 102 | path.moveTo(0, 0); |
| 103 | path.lineTo(50, 0); |
| 104 | path.lineTo(0, 50); |
| 105 | path.close(); |
| 106 | |
| 107 | SkMatrix m; |
| 108 | m.setAll( 0.966006875f , -0.125156224f , 72.0899811f, |
| 109 | -0.00885376986f , -0.112347461f , 64.7121124f, |
| 110 | -8.94321693e-06f, -0.00173384184f, 0.998692870f); |
| 111 | surface->getCanvas()->setMatrix(m); |
| 112 | surface->getCanvas()->drawPath(path, paint); |
Greg Daniel | 0a2464f | 2020-05-14 15:45:44 -0400 | [diff] [blame] | 113 | surface->flushAndSubmit(); |
Brian Osman | 2caecd2 | 2019-09-25 14:02:26 -0400 | [diff] [blame] | 114 | } |
Brian Osman | ae8e063 | 2021-07-26 16:07:35 -0400 | [diff] [blame] | 115 | |
| 116 | DEF_GPUTEST_FOR_ALL_CONTEXTS(PathTest_CrBug1232834, reporter, ctxInfo) { |
Robert Phillips | 461c539 | 2021-08-17 16:42:51 -0400 | [diff] [blame] | 117 | // AAHairlinePathRenderer chops this path to quads that include infinities (and then NaNs). |
Brian Osman | ae8e063 | 2021-07-26 16:07:35 -0400 | [diff] [blame] | 118 | // It used to trigger asserts, now the degenerate quad segments should cause it to be rejected. |
| 119 | SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256); |
| 120 | auto surface(SkSurface::MakeRenderTarget(ctxInfo.directContext(), SkBudgeted::kNo, info)); |
| 121 | |
| 122 | SkPaint paint; |
| 123 | paint.setAntiAlias(true); |
| 124 | paint.setStyle(SkPaint::kStroke_Style); |
| 125 | |
| 126 | SkPath path; |
| 127 | path.moveTo(9.0072E15f, 60); |
| 128 | path.cubicTo(0, 3.40282e+38f, 0, 3.40282e+38f, 0, 0); |
| 129 | |
| 130 | surface->getCanvas()->drawPath(path, paint); |
| 131 | surface->flushAndSubmit(); |
| 132 | } |