Add GrPathUtils::conicHasCusp
Bug: skia:10419 Change-Id: I4250dddf463a66f803148310304f29e0c629bc33 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/397657 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
1a15e57ce6
commit
6475638790
@ -162,6 +162,17 @@ inline void convertQuadToCubic(const SkPoint p[3], SkPoint out[4]) {
|
||||
// point(s) occurred at 180-degree turnaround points on a degenerate flat line.
|
||||
int findCubicConvex180Chops(const SkPoint[], float T[2], bool* areCusps);
|
||||
|
||||
// Returns true if the given conic (or quadratic) has a cusp point. The w value is not necessary in
|
||||
// determining this. If there is a cusp, it can be found at the midtangent.
|
||||
inline bool conicHasCusp(const SkPoint p[3]) {
|
||||
SkVector a = p[1] - p[0];
|
||||
SkVector b = p[2] - p[1];
|
||||
// A conic of any class can only have a cusp if it is a degenerate flat line with a 180 degree
|
||||
// turnarund. To detect this, the beginning and ending tangents must be parallel
|
||||
// (a.cross(b) == 0) and pointing in opposite directions (a.dot(b) < 0).
|
||||
return a.cross(b) == 0 && a.dot(b) < 0;
|
||||
}
|
||||
|
||||
} // namespace GrPathUtils
|
||||
|
||||
#endif
|
||||
|
@ -634,15 +634,6 @@ private:
|
||||
GrVertexColor fDynamicColor;
|
||||
};
|
||||
|
||||
SK_ALWAYS_INLINE static bool conic_has_cusp(const SkPoint p[3]) {
|
||||
SkVector a = p[1] - p[0];
|
||||
SkVector b = p[2] - p[1];
|
||||
// A conic of any class can only have a cusp if it is a degenerate flat line with a 180 degree
|
||||
// turnarund. To detect this, the beginning and ending tangents must be parallel
|
||||
// (a.cross(b) == 0) and pointing in opposite directions (a.dot(b) < 0).
|
||||
return a.cross(b) == 0 && a.dot(b) < 0;
|
||||
}
|
||||
|
||||
SK_ALWAYS_INLINE static bool cubic_has_cusp(const SkPoint p[4]) {
|
||||
using grvx::float2;
|
||||
|
||||
@ -764,7 +755,7 @@ void GrStrokeHardwareTessellator::prepare(GrMeshDrawOp::Target* target,
|
||||
patchWriter.writeLineTo(p[0], p[2]);
|
||||
continue;
|
||||
}
|
||||
if (conic_has_cusp(p)) {
|
||||
if (GrPathUtils::conicHasCusp(p)) {
|
||||
// Cusps are rare, but the tessellation shader can't handle them. Chop the
|
||||
// curve into segments that the shader can handle.
|
||||
SkPoint cusp = SkEvalQuadAt(p, SkFindQuadMidTangent(p));
|
||||
@ -799,7 +790,7 @@ void GrStrokeHardwareTessellator::prepare(GrMeshDrawOp::Target* target,
|
||||
patchWriter.writeLineTo(p[0], p[2]);
|
||||
continue;
|
||||
}
|
||||
if (conic_has_cusp(p)) {
|
||||
if (GrPathUtils::conicHasCusp(p)) {
|
||||
// Cusps are rare, but the tessellation shader can't handle them. Chop the
|
||||
// curve into segments that the shader can handle.
|
||||
SkConic conic(p, *w);
|
||||
|
@ -526,13 +526,7 @@ GrStrokeIndirectTessellator::GrStrokeIndirectTessellator(ShaderFlags shaderFlags
|
||||
// close to what the actual number of subdivisions would have been.
|
||||
[[fallthrough]];
|
||||
case Verb::kQuad: {
|
||||
// Check for a cusp. A conic of any class can only have a cusp if it is a
|
||||
// degenerate flat line with a 180 degree turnarund. To detect this, the
|
||||
// beginning and ending tangents must be parallel (a.cross(b) == 0) and pointing
|
||||
// in opposite directions (a.dot(b) < 0).
|
||||
SkVector a = pts[1] - pts[0];
|
||||
SkVector b = pts[2] - pts[1];
|
||||
if (a.cross(b) == 0 && a.dot(b) < 0) {
|
||||
if (GrPathUtils::conicHasCusp(pts)) {
|
||||
// The curve has a cusp. Draw two lines and a circle instead of a quad.
|
||||
int8_t cuspResolveLevel = counter.countCircles(1);
|
||||
*nextResolveLevel++ = -cuspResolveLevel; // Negative signals a cusp.
|
||||
|
Loading…
Reference in New Issue
Block a user