Migrate to using SkPathBuilder
Change-Id: I86a75670d7b919313747175ca3e49ef7472061fd Reviewed-on: https://skia-review.googlesource.com/c/skia/+/310977 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
6704bc87d2
commit
15a5403cd3
193
gm/aaa.cpp
193
gm/aaa.cpp
@ -9,129 +9,128 @@
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/private/SkFloatBits.h"
|
||||
#include "src/core/SkPathPriv.h"
|
||||
|
||||
#define W 800
|
||||
#define H 800
|
||||
|
||||
DEF_SIMPLE_GM(analytic_antialias_convex, canvas, W, H) {
|
||||
SkPaint p;
|
||||
p.setColor(SK_ColorRED);
|
||||
p.setAntiAlias(true);
|
||||
SkPaint p;
|
||||
p.setColor(SK_ColorRED);
|
||||
p.setAntiAlias(true);
|
||||
|
||||
canvas->clear(0xFFFFFFFF);
|
||||
canvas->clear(0xFFFFFFFF);
|
||||
|
||||
canvas->save();
|
||||
canvas->save();
|
||||
|
||||
SkScalar y = 0;
|
||||
SkScalar y = 0;
|
||||
|
||||
canvas->translate(0, y);
|
||||
canvas->rotate(1);
|
||||
canvas->drawRect({ 20, 20, 200, 200 }, p);
|
||||
canvas->restore();
|
||||
canvas->translate(0, y);
|
||||
canvas->rotate(1);
|
||||
canvas->drawRect({ 20, 20, 200, 200 }, p);
|
||||
canvas->restore();
|
||||
|
||||
y += 200;
|
||||
y += 200;
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(0, y);
|
||||
canvas->rotate(1);
|
||||
canvas->drawRect({ 20, 20, 20.2f, 200 }, p);
|
||||
canvas->drawRect({ 20, 200, 200, 200.1f }, p);
|
||||
canvas->drawCircle(100, 100, 30, p);
|
||||
canvas->restore();
|
||||
canvas->save();
|
||||
canvas->translate(0, y);
|
||||
canvas->rotate(1);
|
||||
canvas->drawRect({ 20, 20, 20.2f, 200 }, p);
|
||||
canvas->drawRect({ 20, 200, 200, 200.1f }, p);
|
||||
canvas->drawCircle(100, 100, 30, p);
|
||||
canvas->restore();
|
||||
|
||||
// The following path is empty but it'll reveal bug chrome:662914
|
||||
SkPath path;
|
||||
path.moveTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f
|
||||
// 77.8075f, 231.626f, 77.8074f, 231.625f, 77.8073f, 231.625f
|
||||
path.cubicTo(SkBits2Float(0x429b9d71), SkBits2Float(0x4367a022),
|
||||
SkBits2Float(0x429b9d64), SkBits2Float(0x4367a009),
|
||||
SkBits2Float(0x429b9d50), SkBits2Float(0x43679ff2));
|
||||
path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f
|
||||
path.close();
|
||||
canvas->drawPath(path, p);
|
||||
// The following path is empty but it'll reveal bug chrome:662914
|
||||
SkPathBuilder path;
|
||||
path.moveTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f
|
||||
// 77.8075f, 231.626f, 77.8074f, 231.625f, 77.8073f, 231.625f
|
||||
path.cubicTo(SkBits2Float(0x429b9d71), SkBits2Float(0x4367a022),
|
||||
SkBits2Float(0x429b9d64), SkBits2Float(0x4367a009),
|
||||
SkBits2Float(0x429b9d50), SkBits2Float(0x43679ff2));
|
||||
path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f
|
||||
path.close();
|
||||
canvas->drawPath(path.detach(), p);
|
||||
|
||||
// The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug:
|
||||
// we should not use any snapped y for the intermediate values whose error may accumulate;
|
||||
// snapping should only be allowed once before updateLine.
|
||||
path.reset();
|
||||
path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f
|
||||
path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f
|
||||
// 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f
|
||||
path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75),
|
||||
SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3));
|
||||
path.close();
|
||||
// Manually setting convexity is required. Otherwise, this path will be considered concave.
|
||||
path.setConvexityType(SkPathConvexityType::kConvex);
|
||||
canvas->drawPath(path, p);
|
||||
// The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug:
|
||||
// we should not use any snapped y for the intermediate values whose error may accumulate;
|
||||
// snapping should only be allowed once before updateLine.
|
||||
path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f
|
||||
path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f
|
||||
// 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f
|
||||
path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75),
|
||||
SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3));
|
||||
path.close();
|
||||
// Manually setting convexity is required. Otherwise, this path will be considered concave.
|
||||
SkPathPriv::SetConvexityType(&path, SkPathConvexityType::kConvex);
|
||||
canvas->drawPath(path.detach(), p);
|
||||
|
||||
// skbug.com/7573
|
||||
y += 200;
|
||||
canvas->save();
|
||||
canvas->translate(0, y);
|
||||
p.setAntiAlias(true);
|
||||
path.reset();
|
||||
path.moveTo(1.98009784f, 9.0162744f);
|
||||
path.lineTo(47.843992f, 10.1922744f);
|
||||
path.lineTo(47.804008f, 11.7597256f);
|
||||
path.lineTo(1.93990216f, 10.5837256f);
|
||||
canvas->drawPath(path, p);
|
||||
canvas->restore();
|
||||
// skbug.com/7573
|
||||
y += 200;
|
||||
canvas->save();
|
||||
canvas->translate(0, y);
|
||||
p.setAntiAlias(true);
|
||||
path.moveTo(1.98009784f, 9.0162744f);
|
||||
path.lineTo(47.843992f, 10.1922744f);
|
||||
path.lineTo(47.804008f, 11.7597256f);
|
||||
path.lineTo(1.93990216f, 10.5837256f);
|
||||
canvas->drawPath(path.detach(), p);
|
||||
canvas->restore();
|
||||
|
||||
// skbug.com/7813
|
||||
// t8888 splits the 800-high canvas into 3 pieces; the boundary is close to 266 and 534
|
||||
path.reset();
|
||||
path.moveTo(700, 266);
|
||||
path.lineTo(710, 266);
|
||||
path.lineTo(710, 534);
|
||||
path.lineTo(700, 534);
|
||||
canvas->drawPath(path, p);
|
||||
// skbug.com/7813
|
||||
// t8888 splits the 800-high canvas into 3 pieces; the boundary is close to 266 and 534
|
||||
path.moveTo(700, 266);
|
||||
path.lineTo(710, 266);
|
||||
path.lineTo(710, 534);
|
||||
path.lineTo(700, 534);
|
||||
canvas->drawPath(path.detach(), p);
|
||||
}
|
||||
|
||||
DEF_SIMPLE_GM(analytic_antialias_general, canvas, W, H) {
|
||||
SkPaint p;
|
||||
p.setColor(SK_ColorRED);
|
||||
p.setAntiAlias(true);
|
||||
SkPaint p;
|
||||
p.setColor(SK_ColorRED);
|
||||
p.setAntiAlias(true);
|
||||
|
||||
canvas->clear(0xFFFFFFFF);
|
||||
canvas->clear(0xFFFFFFFF);
|
||||
|
||||
canvas->save();
|
||||
canvas->rotate(1);
|
||||
const SkScalar R = 115.2f, C = 128.0f;
|
||||
SkPath path;
|
||||
path.moveTo(C + R, C);
|
||||
for (int i = 1; i < 8; ++i) {
|
||||
SkScalar a = 2.6927937f * i;
|
||||
path.lineTo(C + R * SkScalarCos(a), C + R * SkScalarSin(a));
|
||||
}
|
||||
canvas->drawPath(path, p);
|
||||
canvas->restore();
|
||||
canvas->save();
|
||||
canvas->rotate(1);
|
||||
const SkScalar R = 115.2f, C = 128.0f;
|
||||
SkPathBuilder builder;
|
||||
builder.moveTo(C + R, C);
|
||||
for (int i = 1; i < 8; ++i) {
|
||||
SkScalar a = 2.6927937f * i;
|
||||
builder.lineTo(C + R * SkScalarCos(a), C + R * SkScalarSin(a));
|
||||
}
|
||||
SkPath path = builder.detach();
|
||||
canvas->drawPath(path, p);
|
||||
canvas->restore();
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(200, 0);
|
||||
canvas->rotate(1);
|
||||
p.setStyle(SkPaint::kStroke_Style);
|
||||
p.setStrokeWidth(5);
|
||||
canvas->drawPath(path, p);
|
||||
canvas->restore();
|
||||
canvas->save();
|
||||
canvas->translate(200, 0);
|
||||
canvas->rotate(1);
|
||||
p.setStyle(SkPaint::kStroke_Style);
|
||||
p.setStrokeWidth(5);
|
||||
canvas->drawPath(path, p);
|
||||
canvas->restore();
|
||||
|
||||
|
||||
// The following two paths test if we correctly cumulates the alpha on the middle pixel
|
||||
// column where the left rect and the right rect abut.
|
||||
p.setStyle(SkPaint::kFill_Style);
|
||||
canvas->translate(0, 300);
|
||||
path.reset();
|
||||
path.addRect({20, 20, 100.4999f, 100});
|
||||
path.addRect({100.5001f, 20, 200, 100});
|
||||
canvas->drawPath(path, p);
|
||||
// The following two paths test if we correctly cumulates the alpha on the middle pixel
|
||||
// column where the left rect and the right rect abut.
|
||||
p.setStyle(SkPaint::kFill_Style);
|
||||
canvas->translate(0, 300);
|
||||
path.reset();
|
||||
path.addRect({20, 20, 100.4999f, 100});
|
||||
path.addRect({100.5001f, 20, 200, 100});
|
||||
canvas->drawPath(path, p);
|
||||
|
||||
canvas->translate(300, 0);
|
||||
path.reset();
|
||||
path.addRect({20, 20, 100.1f, 100});
|
||||
path.addRect({100.9f, 20, 200, 100});
|
||||
canvas->drawPath(path, p);
|
||||
canvas->translate(300, 0);
|
||||
path.reset();
|
||||
path.addRect({20, 20, 100.1f, 100});
|
||||
path.addRect({100.9f, 20, 200, 100});
|
||||
canvas->drawPath(path, p);
|
||||
}
|
||||
|
||||
DEF_SIMPLE_GM(analytic_antialias_inverse, canvas, W, H) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "gm/gm.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
|
||||
@ -35,11 +35,10 @@ DEF_SIMPLE_GM(bug5252, canvas, 500, 500) {
|
||||
|
||||
canvas->translate(i * 15.f, j * 20.f);
|
||||
canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 15),pa);
|
||||
SkPath path;
|
||||
path.moveTo(6, 6);
|
||||
path.cubicTo(14, 10, 13, 12, 10, 12);
|
||||
path.cubicTo(7, 15, 8, 17, 14, 18);
|
||||
canvas->drawPath(path, pa);
|
||||
canvas->drawPath(SkPathBuilder().moveTo(6, 6)
|
||||
.cubicTo(14, 10, 13, 12, 10, 12)
|
||||
.cubicTo(7, 15, 8, 17, 14, 18)
|
||||
.detach(), pa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ void test_coincident_edges_2(SkCanvas* canvas, const SkPaint& paint) {
|
||||
}
|
||||
// Coincident edges (small ones first, coincident vert on bottom).
|
||||
void test_coincident_edges_3(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
SkPathBuilder path;
|
||||
canvas->save();
|
||||
canvas->translate(200, 500);
|
||||
path.moveTo(20, 80);
|
||||
@ -343,12 +343,12 @@ void test_coincident_edges_3(SkCanvas* canvas, const SkPaint& paint) {
|
||||
path.moveTo(20, 80);
|
||||
path.lineTo(20, 20);
|
||||
path.lineTo(80, 20);
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->drawPath(path.detach(), paint);
|
||||
canvas->restore();
|
||||
}
|
||||
// Coincident edges (big ones first, coincident vert on bottom).
|
||||
void test_coincident_edges_4(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
SkPathBuilder path;
|
||||
canvas->save();
|
||||
canvas->translate(300, 500);
|
||||
path.moveTo(20, 80);
|
||||
@ -357,7 +357,7 @@ void test_coincident_edges_4(SkCanvas* canvas, const SkPaint& paint) {
|
||||
path.moveTo(20, 80);
|
||||
path.lineTo(20, 50);
|
||||
path.lineTo(50, 50);
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->drawPath(path.detach(), paint);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkSize.h"
|
||||
@ -53,214 +53,171 @@ class ConvexPathsGM : public skiagm::GM {
|
||||
}
|
||||
fOnce.accomplished();
|
||||
|
||||
fPaths.push_back().moveTo(0, 0);
|
||||
fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
|
||||
0, 100 * SK_Scalar1);
|
||||
fPaths.back().lineTo(0, 0);
|
||||
SkPathBuilder b;
|
||||
fPaths.push_back(b.moveTo(0, 0)
|
||||
.quadTo(50, 100, 0, 100)
|
||||
.lineTo(0, 0)
|
||||
.detach());
|
||||
|
||||
fPaths.push_back().moveTo(0, 50 * SK_Scalar1);
|
||||
fPaths.back().quadTo(50 * SK_Scalar1, 0,
|
||||
100 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
|
||||
0, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 50)
|
||||
.quadTo(50, 0, 100, 50)
|
||||
.quadTo(50, 100, 0, 50)
|
||||
.detach());
|
||||
|
||||
fPaths.push_back().addRect(0, 0,
|
||||
100 * SK_Scalar1, 100 * SK_Scalar1,
|
||||
SkPathDirection::kCW);
|
||||
|
||||
fPaths.push_back().addRect(0, 0,
|
||||
100 * SK_Scalar1, 100 * SK_Scalar1,
|
||||
SkPathDirection::kCCW);
|
||||
|
||||
fPaths.push_back().addCircle(50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, SkPathDirection::kCW);
|
||||
|
||||
|
||||
fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
|
||||
50 * SK_Scalar1,
|
||||
100 * SK_Scalar1),
|
||||
SkPathDirection::kCW);
|
||||
|
||||
fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
|
||||
100 * SK_Scalar1,
|
||||
5 * SK_Scalar1),
|
||||
SkPathDirection::kCCW);
|
||||
|
||||
fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
|
||||
SK_Scalar1,
|
||||
100 * SK_Scalar1),
|
||||
SkPathDirection::kCCW);
|
||||
|
||||
fPaths.push_back().addRoundRect(SkRect::MakeXYWH(0, 0,
|
||||
SK_Scalar1 * 100,
|
||||
SK_Scalar1 * 100),
|
||||
40 * SK_Scalar1, 20 * SK_Scalar1,
|
||||
SkPathDirection::kCW);
|
||||
fPaths.push_back(SkPath::Rect({0, 0, 100, 100}, SkPathDirection::kCW));
|
||||
fPaths.push_back(SkPath::Rect({0, 0, 100, 100}, SkPathDirection::kCCW));
|
||||
fPaths.push_back(SkPath::Circle(50, 50, 50, SkPathDirection::kCW));
|
||||
fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 50, 100), SkPathDirection::kCW));
|
||||
fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 100, 5), SkPathDirection::kCCW));
|
||||
fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 1, 100), SkPathDirection::kCCW));
|
||||
fPaths.push_back(SkPath::RRect(SkRRect::MakeRectXY({0, 0, 100, 100}, 40, 20),
|
||||
SkPathDirection::kCW));
|
||||
|
||||
// large number of points
|
||||
enum {
|
||||
kLength = 100,
|
||||
kPtsPerSide = (1 << 12),
|
||||
};
|
||||
fPaths.push_back().moveTo(0, 0);
|
||||
b.moveTo(0, 0);
|
||||
for (int i = 1; i < kPtsPerSide; ++i) { // skip the first point due to moveTo.
|
||||
fPaths.back().lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, 0);
|
||||
b.lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, 0);
|
||||
}
|
||||
for (int i = 0; i < kPtsPerSide; ++i) {
|
||||
fPaths.back().lineTo(kLength, kLength * SkIntToScalar(i) / kPtsPerSide);
|
||||
b.lineTo(kLength, kLength * SkIntToScalar(i) / kPtsPerSide);
|
||||
}
|
||||
for (int i = kPtsPerSide; i > 0; --i) {
|
||||
fPaths.back().lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, kLength);
|
||||
b.lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, kLength);
|
||||
}
|
||||
for (int i = kPtsPerSide; i > 0; --i) {
|
||||
fPaths.back().lineTo(0, kLength * SkIntToScalar(i) / kPtsPerSide);
|
||||
b.lineTo(0, kLength * SkIntToScalar(i) / kPtsPerSide);
|
||||
}
|
||||
fPaths.push_back(b.detach());
|
||||
|
||||
// shallow diagonals
|
||||
fPaths.push_back().lineTo(100 * SK_Scalar1, SK_Scalar1);
|
||||
fPaths.back().lineTo(98 * SK_Scalar1, 100 * SK_Scalar1);
|
||||
fPaths.back().lineTo(3 * SK_Scalar1, 96 * SK_Scalar1);
|
||||
fPaths.push_back(SkPath::Polygon({{0,0}, {100,1}, {98,100}, {3,96}}, false));
|
||||
|
||||
fPaths.push_back().arcTo(SkRect::MakeXYWH(0, 0,
|
||||
50 * SK_Scalar1,
|
||||
100 * SK_Scalar1),
|
||||
25 * SK_Scalar1, 130 * SK_Scalar1, false);
|
||||
fPaths.push_back(b.arcTo(SkRect::MakeXYWH(0, 0, 50, 100), 25, 130, false)
|
||||
.detach());
|
||||
|
||||
// cubics
|
||||
fPaths.push_back().cubicTo( 1 * SK_Scalar1, 1 * SK_Scalar1,
|
||||
10 * SK_Scalar1, 90 * SK_Scalar1,
|
||||
0 * SK_Scalar1, 100 * SK_Scalar1);
|
||||
fPaths.push_back().cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
20 * SK_Scalar1, 100 * SK_Scalar1,
|
||||
0 * SK_Scalar1, 0 * SK_Scalar1);
|
||||
fPaths.push_back(b.cubicTo( 1, 1, 10, 90, 0, 100).detach());
|
||||
fPaths.push_back(b.cubicTo(100, 50, 20, 100, 0, 0).detach());
|
||||
|
||||
// path that has a cubic with a repeated first control point and
|
||||
// a repeated last control point.
|
||||
fPaths.push_back().moveTo(SK_Scalar1 * 10, SK_Scalar1 * 10);
|
||||
fPaths.back().cubicTo(10 * SK_Scalar1, 10 * SK_Scalar1,
|
||||
10 * SK_Scalar1, 0,
|
||||
20 * SK_Scalar1, 0);
|
||||
fPaths.back().lineTo(40 * SK_Scalar1, 0);
|
||||
fPaths.back().cubicTo(40 * SK_Scalar1, 0,
|
||||
50 * SK_Scalar1, 0,
|
||||
50 * SK_Scalar1, 10 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(10, 10)
|
||||
.cubicTo(10, 10, 10, 0, 20, 0)
|
||||
.lineTo(40, 0)
|
||||
.cubicTo(40, 0, 50, 0, 50, 10)
|
||||
.detach());
|
||||
|
||||
// path that has two cubics with repeated middle control points.
|
||||
fPaths.push_back().moveTo(SK_Scalar1 * 10, SK_Scalar1 * 10);
|
||||
fPaths.back().cubicTo(10 * SK_Scalar1, 0,
|
||||
10 * SK_Scalar1, 0,
|
||||
20 * SK_Scalar1, 0);
|
||||
fPaths.back().lineTo(40 * SK_Scalar1, 0);
|
||||
fPaths.back().cubicTo(50 * SK_Scalar1, 0,
|
||||
50 * SK_Scalar1, 0,
|
||||
50 * SK_Scalar1, 10 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(10, 10)
|
||||
.cubicTo(10, 0, 10, 0, 20, 0)
|
||||
.lineTo(40, 0)
|
||||
.cubicTo(50, 0, 50, 0, 50, 10)
|
||||
.detach());
|
||||
|
||||
// cubic where last three points are almost a line
|
||||
fPaths.push_back().moveTo(0, 228 * SK_Scalar1 / 8);
|
||||
fPaths.back().cubicTo(628 * SK_Scalar1 / 8, 82 * SK_Scalar1 / 8,
|
||||
1255 * SK_Scalar1 / 8, 141 * SK_Scalar1 / 8,
|
||||
1883 * SK_Scalar1 / 8, 202 * SK_Scalar1 / 8);
|
||||
fPaths.push_back(b.moveTo(0, 228.0f/8)
|
||||
.cubicTo( 628.0f/ 8, 82.0f/8,
|
||||
1255.0f/ 8, 141.0f/8,
|
||||
1883.0f/ 8, 202.0f/8)
|
||||
.detach());
|
||||
|
||||
// flat cubic where the at end point tangents both point outward.
|
||||
fPaths.push_back().moveTo(10 * SK_Scalar1, 0);
|
||||
fPaths.back().cubicTo(0, SK_Scalar1,
|
||||
30 * SK_Scalar1, SK_Scalar1,
|
||||
20 * SK_Scalar1, 0);
|
||||
fPaths.push_back(b.moveTo(10, 0)
|
||||
.cubicTo(0, 1, 30, 1, 20, 0)
|
||||
.detach());
|
||||
|
||||
// flat cubic where initial tangent is in, end tangent out
|
||||
fPaths.push_back().moveTo(0, 0 * SK_Scalar1);
|
||||
fPaths.back().cubicTo(10 * SK_Scalar1, SK_Scalar1,
|
||||
30 * SK_Scalar1, SK_Scalar1,
|
||||
20 * SK_Scalar1, 0);
|
||||
fPaths.push_back(b.moveTo(0, 0)
|
||||
.cubicTo(10, 1, 30, 1, 20, 0)
|
||||
.detach());
|
||||
|
||||
// flat cubic where initial tangent is out, end tangent in
|
||||
fPaths.push_back().moveTo(10 * SK_Scalar1, 0);
|
||||
fPaths.back().cubicTo(0, SK_Scalar1,
|
||||
20 * SK_Scalar1, SK_Scalar1,
|
||||
30 * SK_Scalar1, 0);
|
||||
fPaths.push_back(b.moveTo(10, 0)
|
||||
.cubicTo(0, 1, 20, 1, 30, 0)
|
||||
.detach());
|
||||
|
||||
// triangle where one edge is a degenerate quad
|
||||
fPaths.push_back().moveTo(8.59375f, 45 * SK_Scalar1);
|
||||
fPaths.back().quadTo(16.9921875f, 45 * SK_Scalar1,
|
||||
31.25f, 45 * SK_Scalar1);
|
||||
fPaths.back().lineTo(100 * SK_Scalar1, 100 * SK_Scalar1);
|
||||
fPaths.back().lineTo(8.59375f, 45 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(8.59375f, 45)
|
||||
.quadTo(16.9921875f, 45,
|
||||
31.25f, 45)
|
||||
.lineTo(100, 100)
|
||||
.lineTo(8.59375f, 45)
|
||||
.detach());
|
||||
|
||||
// triangle where one edge is a quad with a repeated point
|
||||
fPaths.push_back().moveTo(0, 25 * SK_Scalar1);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 0);
|
||||
fPaths.back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1, 50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 25)
|
||||
.lineTo(50, 0)
|
||||
.quadTo(50, 50, 50, 50)
|
||||
.detach());
|
||||
|
||||
// triangle where one edge is a cubic with a 2x repeated point
|
||||
fPaths.push_back().moveTo(0, 25 * SK_Scalar1);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 0);
|
||||
fPaths.back().cubicTo(50 * SK_Scalar1, 0,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 25)
|
||||
.lineTo(50, 0)
|
||||
.cubicTo(50, 0, 50, 50, 50, 50)
|
||||
.detach());
|
||||
|
||||
// triangle where one edge is a quad with a nearly repeated point
|
||||
fPaths.push_back().moveTo(0, 25 * SK_Scalar1);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 0);
|
||||
fPaths.back().quadTo(50 * SK_Scalar1, 49.95f,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 25)
|
||||
.lineTo(50, 0)
|
||||
.quadTo(50, 49.95f, 50, 50)
|
||||
.detach());
|
||||
|
||||
// triangle where one edge is a cubic with a 3x nearly repeated point
|
||||
fPaths.push_back().moveTo(0, 25 * SK_Scalar1);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 0);
|
||||
fPaths.back().cubicTo(50 * SK_Scalar1, 49.95f,
|
||||
50 * SK_Scalar1, 49.97f,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 25)
|
||||
.lineTo(50, 0)
|
||||
.cubicTo(50, 49.95f, 50, 49.97f, 50, 50)
|
||||
.detach());
|
||||
|
||||
// triangle where there is a point degenerate cubic at one corner
|
||||
fPaths.push_back().moveTo(0, 25 * SK_Scalar1);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 0);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.back().cubicTo(50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 25)
|
||||
.lineTo(50, 0)
|
||||
.lineTo(50, 50)
|
||||
.cubicTo(50, 50, 50, 50, 50, 50)
|
||||
.detach());
|
||||
|
||||
// point line
|
||||
fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.back().lineTo(50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(SkPath::Line({50, 50}, {50, 50}));
|
||||
|
||||
// point quad
|
||||
fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(50, 50)
|
||||
.quadTo(50, 50, 50, 50)
|
||||
.detach());
|
||||
|
||||
// point cubic
|
||||
fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.back().cubicTo(50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(50, 50)
|
||||
.cubicTo(50, 50, 50, 50, 50, 50)
|
||||
.detach());
|
||||
|
||||
// moveTo only paths
|
||||
fPaths.push_back().moveTo(0, 0);
|
||||
fPaths.back().moveTo(0, 0);
|
||||
fPaths.back().moveTo(SK_Scalar1, SK_Scalar1);
|
||||
fPaths.back().moveTo(SK_Scalar1, SK_Scalar1);
|
||||
fPaths.back().moveTo(10 * SK_Scalar1, 10 * SK_Scalar1);
|
||||
fPaths.push_back(b.moveTo(0, 0)
|
||||
.moveTo(0, 0)
|
||||
.moveTo(1, 1)
|
||||
.moveTo(1, 1)
|
||||
.moveTo(10, 10)
|
||||
.detach());
|
||||
|
||||
fPaths.push_back().moveTo(0, 0);
|
||||
fPaths.back().moveTo(0, 0);
|
||||
fPaths.push_back(b.moveTo(0, 0)
|
||||
.moveTo(0, 0)
|
||||
.detach());
|
||||
|
||||
// line degenerate
|
||||
fPaths.push_back().lineTo(100 * SK_Scalar1, 100 * SK_Scalar1);
|
||||
fPaths.push_back().quadTo(100 * SK_Scalar1, 100 * SK_Scalar1, 0, 0);
|
||||
fPaths.push_back().quadTo(100 * SK_Scalar1, 100 * SK_Scalar1,
|
||||
50 * SK_Scalar1, 50 * SK_Scalar1);
|
||||
fPaths.push_back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1,
|
||||
100 * SK_Scalar1, 100 * SK_Scalar1);
|
||||
fPaths.push_back().cubicTo(0, 0,
|
||||
0, 0,
|
||||
100 * SK_Scalar1, 100 * SK_Scalar1);
|
||||
fPaths.push_back(b.lineTo(100, 100).detach());
|
||||
fPaths.push_back(b.quadTo(100, 100, 0, 0).detach());
|
||||
fPaths.push_back(b.quadTo(100, 100, 50, 50).detach());
|
||||
fPaths.push_back(b.quadTo(50, 50, 100, 100).detach());
|
||||
fPaths.push_back(b.cubicTo(0, 0, 0, 0, 100, 100).detach());
|
||||
|
||||
// skbug.com/8928
|
||||
fPaths.push_back().moveTo(16.875f, 192.594f);
|
||||
fPaths.back().cubicTo(45.625f, 192.594f, 74.375f, 192.594f, 103.125f, 192.594f);
|
||||
fPaths.back().cubicTo(88.75f, 167.708f, 74.375f, 142.823f, 60, 117.938f);
|
||||
fPaths.back().cubicTo(45.625f, 142.823f, 31.25f, 167.708f, 16.875f, 192.594f);
|
||||
fPaths.back().close();
|
||||
fPaths.push_back(b.moveTo(16.875f, 192.594f)
|
||||
.cubicTo(45.625f, 192.594f, 74.375f, 192.594f, 103.125f, 192.594f)
|
||||
.cubicTo(88.75f, 167.708f, 74.375f, 142.823f, 60, 117.938f)
|
||||
.cubicTo(45.625f, 142.823f, 31.25f, 167.708f, 16.875f, 192.594f)
|
||||
.close()
|
||||
.detach());
|
||||
SkMatrix m;
|
||||
m.setAll(0.1f, 0, -1, 0, 0.115207f, -2.64977f, 0, 0, 1);
|
||||
fPaths.back().transform(m);
|
||||
@ -276,16 +233,16 @@ class ConvexPathsGM : public skiagm::GM {
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
SkRandom rand;
|
||||
canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
|
||||
canvas->translate(20, 20);
|
||||
|
||||
// As we've added more paths this has gotten pretty big. Scale the whole thing down.
|
||||
canvas->scale(2 * SK_Scalar1 / 3, 2 * SK_Scalar1 / 3);
|
||||
canvas->scale(2.0f/3, 2.0f/3);
|
||||
|
||||
for (int i = 0; i < fPaths.count(); ++i) {
|
||||
canvas->save();
|
||||
// position the path, and make it at off-integer coords.
|
||||
canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 10,
|
||||
SK_Scalar1 * 200 * (i / 5) + 9 * SK_Scalar1 / 10);
|
||||
canvas->translate(200.0f * (i % 5) + 1.0f/10,
|
||||
200.0f * (i / 5) + 9.0f/10);
|
||||
SkColor color = rand.nextU();
|
||||
color |= 0xff000000;
|
||||
paint.setColor(color);
|
||||
|
@ -12,9 +12,7 @@
|
||||
#include "include/effects/SkDashPathEffect.h"
|
||||
|
||||
DEF_SIMPLE_GM(crbug_1113794, canvas, 600, 200) {
|
||||
SkPath path;
|
||||
path.moveTo(50.f, 80.f);
|
||||
path.lineTo(50.f, 20.f);
|
||||
SkPath path = SkPath::Line({50.f, 80.f}, {50.f, 20.f});
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
|
@ -1816,7 +1816,7 @@ public:
|
||||
bool isValid() const { return this->isValidImpl() && fPathRef->isValid(); }
|
||||
|
||||
private:
|
||||
SkPath(sk_sp<SkPathRef>, SkPathFillType, bool isVolatile);
|
||||
SkPath(sk_sp<SkPathRef>, SkPathFillType, bool isVolatile, SkPathConvexityType);
|
||||
|
||||
sk_sp<SkPathRef> fPathRef;
|
||||
int fLastMoveToIndex;
|
||||
|
@ -216,6 +216,9 @@ private:
|
||||
int fIsAStart = -1; // tracks direction iff fIsA is not unknown
|
||||
bool fIsACCW = false; // tracks direction iff fIsA is not unknown
|
||||
|
||||
// for testing
|
||||
SkPathConvexityType fConvexity = SkPathConvexityType::kUnknown;
|
||||
|
||||
int countVerbs() const { return fVerbs.count(); }
|
||||
|
||||
// called right before we add a (non-move) verb
|
||||
@ -227,6 +230,11 @@ private:
|
||||
}
|
||||
|
||||
SkPath make(sk_sp<SkPathRef>) const;
|
||||
|
||||
// For testing
|
||||
void privateSetConvexityType(SkPathConvexityType c) { fConvexity = c; }
|
||||
|
||||
friend class SkPathPriv;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "include/core/SkContourMeasure.h"
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "modules/skottie/src/SkottieJson.h"
|
||||
#include "modules/skottie/src/SkottieValue.h"
|
||||
#include "modules/skottie/src/animator/Animator.h"
|
||||
@ -88,12 +89,12 @@ public:
|
||||
}
|
||||
|
||||
// Finally, this looks like a legitimate spatial keyframe.
|
||||
SkPath p;
|
||||
SkPathBuilder p;
|
||||
p.moveTo (prev_val.v2.x , prev_val.v2.y);
|
||||
p.cubicTo(prev_val.v2.x + fTo.x, prev_val.v2.y + fTo.y,
|
||||
val.v2.x + fTi.x, val.v2.y + fTi.y,
|
||||
val.v2.x, val.v2.y);
|
||||
prev_val.cmeasure = SkContourMeasureIter(p, false).next();
|
||||
prev_val.cmeasure = SkContourMeasureIter(p.detach(), false).next();
|
||||
}
|
||||
|
||||
bool parseKFValue(const AnimationBuilder&,
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "include/core/SkRRect.h"
|
||||
#include "include/utils/SkRandom.h"
|
||||
#include "samplecode/Sample.h"
|
||||
@ -102,20 +103,20 @@ protected:
|
||||
SkVector::Make(0, 0));
|
||||
|
||||
// Background decoration.
|
||||
SkPath bgPath;
|
||||
bgPath.moveTo(kBounds.left() , fieldBounds.top());
|
||||
bgPath.lineTo(kBounds.right(), fieldBounds.top());
|
||||
bgPath.moveTo(kBounds.left() , fieldBounds.bottom());
|
||||
bgPath.lineTo(kBounds.right(), fieldBounds.bottom());
|
||||
SkPathBuilder bgPath;
|
||||
bgPath.moveTo(kBounds.left() , fieldBounds.top())
|
||||
.lineTo(kBounds.right(), fieldBounds.top())
|
||||
.moveTo(kBounds.left() , fieldBounds.bottom())
|
||||
.lineTo(kBounds.right(), fieldBounds.bottom());
|
||||
// TODO: stroke-dash support would come in handy right about now.
|
||||
for (uint32_t i = 0; i < kBackgroundDashCount; ++i) {
|
||||
bgPath.moveTo(kBounds.centerX(),
|
||||
kBounds.top() + (i + 0.25f) * kBounds.height() / kBackgroundDashCount);
|
||||
bgPath.lineTo(kBounds.centerX(),
|
||||
kBounds.top() + (i + 0.25f) * kBounds.height() / kBackgroundDashCount)
|
||||
.lineTo(kBounds.centerX(),
|
||||
kBounds.top() + (i + 0.75f) * kBounds.height() / kBackgroundDashCount);
|
||||
}
|
||||
|
||||
auto bg_path = sksg::Path::Make(bgPath);
|
||||
auto bg_path = sksg::Path::Make(bgPath.detach());
|
||||
auto bg_paint = sksg::Color::Make(SK_ColorBLACK);
|
||||
bg_paint->setStyle(SkPaint::kStroke_Style);
|
||||
bg_paint->setStrokeWidth(kBackgroundStroke);
|
||||
|
@ -147,10 +147,10 @@ SkPath::SkPath()
|
||||
fIsVolatile = false;
|
||||
}
|
||||
|
||||
SkPath::SkPath(sk_sp<SkPathRef> pr, SkPathFillType ft, bool isVolatile)
|
||||
SkPath::SkPath(sk_sp<SkPathRef> pr, SkPathFillType ft, bool isVolatile, SkPathConvexityType ct)
|
||||
: fPathRef(std::move(pr))
|
||||
, fLastMoveToIndex(INITIAL_LASTMOVETOINDEX_VALUE)
|
||||
, fConvexity((uint8_t)SkPathConvexityType::kUnknown)
|
||||
, fConvexity((uint8_t)ct)
|
||||
, fFirstDirection(SkPathPriv::kUnknown_FirstDirection)
|
||||
, fFillType((unsigned)ft)
|
||||
, fIsVolatile(isVolatile)
|
||||
@ -3402,7 +3402,7 @@ SkPath SkPath::Make(const SkPoint pts[], int pointCount,
|
||||
SkTDArray<uint8_t>(vbs, verbCount),
|
||||
SkTDArray<SkScalar>(ws, info.weights),
|
||||
info.segmentMask)),
|
||||
ft, isVolatile);
|
||||
ft, isVolatile, SkPathConvexityType::kUnknown);
|
||||
}
|
||||
|
||||
SkPath SkPath::Rect(const SkRect& r, SkPathDirection dir) {
|
||||
|
@ -32,6 +32,7 @@ SkPathBuilder& SkPathBuilder::reset() {
|
||||
fSegmentMask = 0;
|
||||
fLastMovePoint = {0, 0};
|
||||
fNeedsMoveVerb = true;
|
||||
fConvexity = SkPathConvexityType::kUnknown;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -149,7 +150,7 @@ SkPath SkPathBuilder::make(sk_sp<SkPathRef> pr) const {
|
||||
case kIsA_RRect: pr->setIsRRect(true, fIsACCW, fIsAStart); break;
|
||||
default: break;
|
||||
}
|
||||
return SkPath(std::move(pr), fFillType, fIsVolatile);
|
||||
return SkPath(std::move(pr), fFillType, fIsVolatile, fConvexity);
|
||||
}
|
||||
|
||||
SkPath SkPathBuilder::snapshot() {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef SkPathPriv_DEFINED
|
||||
#define SkPathPriv_DEFINED
|
||||
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "include/private/SkIDChangeListener.h"
|
||||
#include "src/core/SkPathView.h"
|
||||
|
||||
@ -392,6 +392,10 @@ public:
|
||||
ed.writablePoints()[index] = pt;
|
||||
path->dirtyAfterEdit();
|
||||
}
|
||||
|
||||
static void SetConvexityType(SkPathBuilder* builder, SkPathConvexityType c) {
|
||||
builder->privateSetConvexityType(c);
|
||||
}
|
||||
};
|
||||
|
||||
// Lightweight variant of SkPath::Iter that only returns segments (e.g. lines/conics).
|
||||
|
Loading…
Reference in New Issue
Block a user