Add a quadratic cusp to trickycubicstrokes
Bug: skia:10419 Change-Id: I37f04f442485c13cc7af60e0573b23dfaa5378bf Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317267 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
parent
194b9b9334
commit
5c3e1a969e
@ -30,31 +30,34 @@ enum class CellFillMode {
|
||||
|
||||
struct TrickyCubic {
|
||||
SkPoint fPoints[4];
|
||||
int fNumPts;
|
||||
CellFillMode fFillMode;
|
||||
float fScale = 1;
|
||||
};
|
||||
|
||||
static const TrickyCubic kTrickyCubics[] = {
|
||||
{{{122, 737}, {348, 553}, {403, 761}, {400, 760}}, CellFillMode::kStretch},
|
||||
{{{244, 520}, {244, 518}, {1141, 634}, {394, 688}}, CellFillMode::kStretch},
|
||||
{{{550, 194}, {138, 130}, {1035, 246}, {288, 300}}, CellFillMode::kStretch},
|
||||
{{{226, 733}, {556, 779}, {-43, 471}, {348, 683}}, CellFillMode::kStretch},
|
||||
{{{268, 204}, {492, 304}, {352, 23}, {433, 412}}, CellFillMode::kStretch},
|
||||
{{{172, 480}, {396, 580}, {256, 299}, {338, 677}}, CellFillMode::kStretch},
|
||||
{{{731, 340}, {318, 252}, {1026, -64}, {367, 265}}, CellFillMode::kStretch},
|
||||
{{{475, 708}, {62, 620}, {770, 304}, {220, 659}}, CellFillMode::kStretch},
|
||||
{{{0, 0}, {128, 128}, {128, 0}, {0, 128}}, CellFillMode::kCenter}, // Perfect cusp
|
||||
{{{0,.01f}, {128,127.999f}, {128,.01f}, {0,127.99f}}, CellFillMode::kCenter}, // Near-cusp
|
||||
{{{0,-.01f}, {128,128.001f}, {128,-.01f}, {0,128.001f}}, CellFillMode::kCenter}, // Near-cusp
|
||||
{{{0,0}, {0,-10}, {0,-10}, {0,10}}, CellFillMode::kCenter, 1.098283f}, // Flat line with 180
|
||||
{{{10,0}, {0,0}, {20,0}, {10,0}}, CellFillMode::kStretch}, // Flat line with 2 180s
|
||||
{{{39,-39}, {40,-40}, {40,-40}, {0,0}}, CellFillMode::kStretch}, // Flat diagonal with 180
|
||||
{{{40, 40}, {0, 0}, {200, 200}, {0, 0}}, CellFillMode::kStretch}, // Diag with an internal 180
|
||||
{{{0,0}, {1e-2f,0}, {-1e-2f,0}, {0,0}}, CellFillMode::kCenter}, // Circle
|
||||
{{{400.75f,100.05f}, {400.75f,100.05f}, {100.05f,300.95f}, {100.05f,300.95f}},
|
||||
{{{122, 737}, {348, 553}, {403, 761}, {400, 760}}, 4, CellFillMode::kStretch},
|
||||
{{{244, 520}, {244, 518}, {1141, 634}, {394, 688}}, 4, CellFillMode::kStretch},
|
||||
{{{550, 194}, {138, 130}, {1035, 246}, {288, 300}}, 4, CellFillMode::kStretch},
|
||||
{{{226, 733}, {556, 779}, {-43, 471}, {348, 683}}, 4, CellFillMode::kStretch},
|
||||
{{{268, 204}, {492, 304}, {352, 23}, {433, 412}}, 4, CellFillMode::kStretch},
|
||||
{{{172, 480}, {396, 580}, {256, 299}, {338, 677}}, 4, CellFillMode::kStretch},
|
||||
{{{731, 340}, {318, 252}, {1026, -64}, {367, 265}}, 4, CellFillMode::kStretch},
|
||||
{{{475, 708}, {62, 620}, {770, 304}, {220, 659}}, 4, CellFillMode::kStretch},
|
||||
{{{0, 0}, {128, 128}, {128, 0}, {0, 128}}, 4, CellFillMode::kCenter}, // Perfect cusp
|
||||
{{{0,.01f}, {128,127.999f}, {128,.01f}, {0,127.99f}}, 4, CellFillMode::kCenter}, // Near-cusp
|
||||
{{{0,-.01f}, {128,128.001f}, {128,-.01f}, {0,128.001f}}, 4, CellFillMode::kCenter}, // Near-cusp
|
||||
{{{0,0}, {0,-10}, {0,-10}, {0,10}}, 4, CellFillMode::kCenter, 1.098283f}, // Flat line with 180
|
||||
{{{10,0}, {0,0}, {20,0}, {10,0}}, 4, CellFillMode::kStretch}, // Flat line with 2 180s
|
||||
{{{39,-39}, {40,-40}, {40,-40}, {0,0}}, 4, CellFillMode::kStretch}, // Flat diagonal with 180
|
||||
{{{40, 40}, {0, 0}, {200, 200}, {0, 0}}, 4, CellFillMode::kStretch}, // Diag w/ an internal 180
|
||||
{{{0,0}, {1e-2f,0}, {-1e-2f,0}, {0,0}}, 4, CellFillMode::kCenter}, // Circle
|
||||
{{{400.75f,100.05f}, {400.75f,100.05f}, {100.05f,300.95f}, {100.05f,300.95f}}, 4,
|
||||
CellFillMode::kStretch}, // Flat line with no turns
|
||||
{{{0.5f,0}, {0,0}, {20,0}, {10,0}}, CellFillMode::kStretch}, // Flat line with 2 180s
|
||||
{{{10,0}, {0,0}, {10,0}, {10,0}}, CellFillMode::kStretch}, // Flat line with a 180
|
||||
{{{0.5f,0}, {0,0}, {20,0}, {10,0}}, 4, CellFillMode::kStretch}, // Flat line with 2 180s
|
||||
{{{10,0}, {0,0}, {10,0}, {10,0}}, 4, CellFillMode::kStretch}, // Flat line with a 180
|
||||
{{{1,1}, {2,1}, {1,1}, {std::numeric_limits<float>::quiet_NaN(), 0}}, 3,
|
||||
CellFillMode::kStretch}, // Flat QUAD with a 180
|
||||
};
|
||||
|
||||
static SkRect calc_tight_cubic_bounds(const SkPoint P[4], int depth=5) {
|
||||
@ -74,6 +77,11 @@ static SkRect calc_tight_cubic_bounds(const SkPoint P[4], int depth=5) {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
static SkPoint lerp(const SkPoint& a, const SkPoint& b, float T) {
|
||||
SkASSERT(1 != T); // The below does not guarantee lerp(a, b, 1) === b.
|
||||
return (b - a) * T + a;
|
||||
}
|
||||
|
||||
enum class FillMode {
|
||||
kCenter,
|
||||
kScale
|
||||
@ -111,16 +119,24 @@ protected:
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
p[j] *= trickyCubic.fScale;
|
||||
}
|
||||
this->drawStroke(canvas, p, i, trickyCubic.fFillMode);
|
||||
this->drawStroke(canvas, p, trickyCubic.fNumPts, i, trickyCubic.fFillMode);
|
||||
}
|
||||
}
|
||||
|
||||
void drawStroke(SkCanvas* canvas, const SkPoint p[4], int cellID, CellFillMode fillMode) {
|
||||
void drawStroke(SkCanvas* canvas, const SkPoint p[], int numPts, int cellID,
|
||||
CellFillMode fillMode) {
|
||||
auto cellRect = SkRect::MakeXYWH((cellID % kNumCols) * kCellSize,
|
||||
(cellID / kNumCols) * kCellSize,
|
||||
kCellSize, kCellSize);
|
||||
|
||||
SkRect strokeBounds = calc_tight_cubic_bounds(p);
|
||||
SkRect strokeBounds;
|
||||
if (numPts == 4) {
|
||||
strokeBounds = calc_tight_cubic_bounds(p);
|
||||
} else {
|
||||
SkASSERT(numPts == 3);
|
||||
SkPoint asCubic[4] = {p[0], lerp(p[0], p[1], 2/3.f), lerp(p[1], p[2], 1/3.f), p[2]};
|
||||
strokeBounds = calc_tight_cubic_bounds(asCubic);
|
||||
}
|
||||
strokeBounds.outset(kStrokeWidth, kStrokeWidth);
|
||||
|
||||
SkMatrix matrix;
|
||||
@ -136,7 +152,14 @@ protected:
|
||||
SkAutoCanvasRestore acr(canvas, true);
|
||||
canvas->concat(matrix);
|
||||
fStrokePaint.setStrokeWidth(kStrokeWidth / matrix.getMaxScale());
|
||||
canvas->drawPath(SkPath().moveTo(p[0]).cubicTo(p[1], p[2], p[3]), fStrokePaint);
|
||||
SkPath path = SkPath().moveTo(p[0]);
|
||||
if (numPts == 4) {
|
||||
path.cubicTo(p[1], p[2], p[3]);
|
||||
} else {
|
||||
SkASSERT(numPts == 3);
|
||||
path.quadTo(p[1], p[2]);
|
||||
}
|
||||
canvas->drawPath(path, fStrokePaint);
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user