aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders/gradients/SkTwoPointConicalGradient.cpp
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-06-28 14:46:54 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-28 19:15:49 +0000
commit2e409009fb715400a0d64612c57187465c12790c (patch)
treec70f520634c129ac32d1f90ff494fa587f632f27 /src/shaders/gradients/SkTwoPointConicalGradient.cpp
parentc02de0b844fdb04e28e45ed5bbdd5eb0935c42d2 (diff)
2pt conical stage for focal-pt-on-edge case
When the focal point is on the edge of the end circle, the quadratic equation devolves to linear. Add a stage to handle this case. As a complication, this case can produce "degenerate" values: 1) t == NaN 2) R(t) < 0 For these, we're supposed to draw transparent black - which means overwriting the color from the gradient stage. To support this, build a 0/1 vector mask in the context, and apply it post-gradient-stage. Change-Id: Ice4e3243abfd8c784bb810f6c310aed7a4ac7dc8 Reviewed-on: https://skia-review.googlesource.com/21111 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src/shaders/gradients/SkTwoPointConicalGradient.cpp')
-rw-r--r--src/shaders/gradients/SkTwoPointConicalGradient.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/shaders/gradients/SkTwoPointConicalGradient.cpp b/src/shaders/gradients/SkTwoPointConicalGradient.cpp
index d33fbac868..0f48cc20e3 100644
--- a/src/shaders/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/shaders/gradients/SkTwoPointConicalGradient.cpp
@@ -428,7 +428,8 @@ void SkTwoPointConicalGradient::toString(SkString* str) const {
bool SkTwoPointConicalGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
SkMatrix* matrix,
- SkRasterPipeline* p) const {
+ SkRasterPipeline* p,
+ SkRasterPipeline* postPipeline) const {
const auto dCenter = (fCenter1 - fCenter2).length();
const auto dRadius = fRadius2 - fRadius1;
SkASSERT(dRadius >= 0);
@@ -468,17 +469,21 @@ bool SkTwoPointConicalGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
// Since we've squashed the centers into a unit vector, we must also scale
// all the coefficient variables by (1 / dCenter).
const auto coeffA = 1 - dRadius * dRadius / (dCenter * dCenter);
- if (SkScalarNearlyZero(coeffA)) {
- // We only handle well behaved quadratic cases for now.
- return false;
- }
-
auto* ctx = alloc->make<SkJumper_2PtConicalCtx>();
ctx->fCoeffA = coeffA;
ctx->fInvCoeffA = 1 / coeffA;
ctx->fR0 = fRadius1 / dCenter;
ctx->fDR = dRadius / dCenter;
- p->append(SkRasterPipeline::xy_to_2pt_conical, ctx);
+ if (SkScalarNearlyZero(coeffA)) {
+ // The focal point is on the edge of the end circle.
+ p->append(SkRasterPipeline::xy_to_2pt_conical_linear, ctx);
+ // To handle degenerate values (NaN, r < 0), the t stage sets up a scale/mask
+ // context, which we post-apply to force transparent black.
+ postPipeline->append(SkRasterPipeline::vector_scale, &ctx->fMask);
+ } else {
+ p->append(SkRasterPipeline::xy_to_2pt_conical_quadratic, ctx);
+ }
+
return true;
}