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.
|
// point(s) occurred at 180-degree turnaround points on a degenerate flat line.
|
||||||
int findCubicConvex180Chops(const SkPoint[], float T[2], bool* areCusps);
|
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
|
} // namespace GrPathUtils
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -634,15 +634,6 @@ private:
|
|||||||
GrVertexColor fDynamicColor;
|
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]) {
|
SK_ALWAYS_INLINE static bool cubic_has_cusp(const SkPoint p[4]) {
|
||||||
using grvx::float2;
|
using grvx::float2;
|
||||||
|
|
||||||
@ -764,7 +755,7 @@ void GrStrokeHardwareTessellator::prepare(GrMeshDrawOp::Target* target,
|
|||||||
patchWriter.writeLineTo(p[0], p[2]);
|
patchWriter.writeLineTo(p[0], p[2]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (conic_has_cusp(p)) {
|
if (GrPathUtils::conicHasCusp(p)) {
|
||||||
// Cusps are rare, but the tessellation shader can't handle them. Chop the
|
// Cusps are rare, but the tessellation shader can't handle them. Chop the
|
||||||
// curve into segments that the shader can handle.
|
// curve into segments that the shader can handle.
|
||||||
SkPoint cusp = SkEvalQuadAt(p, SkFindQuadMidTangent(p));
|
SkPoint cusp = SkEvalQuadAt(p, SkFindQuadMidTangent(p));
|
||||||
@ -799,7 +790,7 @@ void GrStrokeHardwareTessellator::prepare(GrMeshDrawOp::Target* target,
|
|||||||
patchWriter.writeLineTo(p[0], p[2]);
|
patchWriter.writeLineTo(p[0], p[2]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (conic_has_cusp(p)) {
|
if (GrPathUtils::conicHasCusp(p)) {
|
||||||
// Cusps are rare, but the tessellation shader can't handle them. Chop the
|
// Cusps are rare, but the tessellation shader can't handle them. Chop the
|
||||||
// curve into segments that the shader can handle.
|
// curve into segments that the shader can handle.
|
||||||
SkConic conic(p, *w);
|
SkConic conic(p, *w);
|
||||||
|
@ -526,13 +526,7 @@ GrStrokeIndirectTessellator::GrStrokeIndirectTessellator(ShaderFlags shaderFlags
|
|||||||
// close to what the actual number of subdivisions would have been.
|
// close to what the actual number of subdivisions would have been.
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case Verb::kQuad: {
|
case Verb::kQuad: {
|
||||||
// Check for a cusp. A conic of any class can only have a cusp if it is a
|
if (GrPathUtils::conicHasCusp(pts)) {
|
||||||
// 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) {
|
|
||||||
// The curve has a cusp. Draw two lines and a circle instead of a quad.
|
// The curve has a cusp. Draw two lines and a circle instead of a quad.
|
||||||
int8_t cuspResolveLevel = counter.countCircles(1);
|
int8_t cuspResolveLevel = counter.countCircles(1);
|
||||||
*nextResolveLevel++ = -cuspResolveLevel; // Negative signals a cusp.
|
*nextResolveLevel++ = -cuspResolveLevel; // Negative signals a cusp.
|
||||||
|
Loading…
Reference in New Issue
Block a user