38 matrix->postTranslate(-1, 0);
39 matrix->postScale(-1, 1);
47 const SkPoint to[2] = { {0, 0}, {1, 0} };
52 matrix->postConcat(focalMatrix);
88 const SkPoint centers[2] = { c0 , c1 };
89 const SkPoint unitvec[2] = { {0, 0}, {1, 0} };
101 const auto dCenter = (c0 - c1).
length();
102 if (!focalData.
set(r0 / dCenter, r1 / dCenter, &gradientMatrix)) {
106 return SkLocalMatrixShader::MakeWrapped<SkConicalGradient>(
107 localMatrix, c0, r0, c1, r1, desc, gradientType, gradientMatrix, focalData);
121 , fRadius1(startRadius)
122 , fRadius2(endRadius)
125 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2);
143 info->fPoint[0] = fCenter1;
144 info->fPoint[1] = fCenter2;
145 info->fRadius[0] = fRadius1;
146 info->fRadius[1] = fRadius2;
151 return GradientType::kConical;
155 DescriptorScope desc;
156 SkMatrix legacyLocalMatrix, *lmPtr =
nullptr;
157 if (!desc.unflatten(
buffer, &legacyLocalMatrix)) {
161 lmPtr = &legacyLocalMatrix;
176 std::move(
desc.fColorSpace),
186 buffer.writePoint(fCenter1);
187 buffer.writePoint(fCenter2);
188 buffer.writeScalar(fRadius1);
189 buffer.writeScalar(fRadius2);
195 const auto dRadius = fRadius2 - fRadius1;
198 p->append(SkRasterPipelineOp::xy_to_radius);
201 auto scale = std::max(fRadius1, fRadius2) / dRadius;
202 auto bias = -fRadius1 / dRadius;
211 ctx->fP0 = scaledR0 * scaledR0;
212 p->append(SkRasterPipelineOp::xy_to_2pt_conical_strip, ctx);
213 p->append(SkRasterPipelineOp::mask_2pt_conical_nan, ctx);
214 postPipeline->
append(SkRasterPipelineOp::apply_vector_mask, &ctx->fMask);
219 ctx->
fP0 = 1 / fFocalData.
fR1;
223 p->append(SkRasterPipelineOp::xy_to_2pt_conical_focal_on_circle);
225 p->append(SkRasterPipelineOp::xy_to_2pt_conical_well_behaved, ctx);
227 p->append(SkRasterPipelineOp::xy_to_2pt_conical_smaller, ctx);
229 p->append(SkRasterPipelineOp::xy_to_2pt_conical_greater, ctx);
233 p->append(SkRasterPipelineOp::mask_2pt_conical_degenerates, ctx);
235 if (1 - fFocalData.
fFocalX < 0) {
236 p->append(SkRasterPipelineOp::negate_x);
239 p->append(SkRasterPipelineOp::alter_2pt_conical_compensate_focal, ctx);
242 p->append(SkRasterPipelineOp::alter_2pt_conical_unswap);
245 postPipeline->
append(SkRasterPipelineOp::apply_vector_mask, &ctx->fMask);
250#define EXPAND_1_COLOR(count) \
254 tmp[0] = tmp[1] = colors[0]; \
272 if (startRadius < 0 || endRadius < 0) {
292 static constexpr SkScalar circlePos[3] = {0, 1, 1};
293 SkColor4f reColors[3] = {colors[0], colors[0], colors[colorCount - 1]};
297 std::move(colorSpace),
306 colors,
pos, colorCount, std::move(colorSpace), mode);
314 std::move(colorSpace),
325 if (localMatrix && !localMatrix->
invert(
nullptr)) {
331 colors, std::move(colorSpace),
pos, colorCount, mode, interpolation);
352 converter.fColors4f.begin(),
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
void SkRegisterConicalGradientShaderFlattenable()
#define EXPAND_1_COLOR(count)
#define SK_REGISTER_FLATTENABLE(type)
static constexpr float sk_ieee_float_divide(float numer, float denom)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
static sk_sp< SkShader > MakeRadial()
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
SkConicalGradient(const SkPoint &c0, SkScalar r0, const SkPoint &c1, SkScalar r1, const Descriptor &, Type, const SkMatrix &, const FocalData &)
SkScalar getCenterX1() const
void flatten(SkWriteBuffer &buffer) const override
GradientType asGradient(GradientInfo *info, SkMatrix *localMatrix) const override
void appendGradientStages(SkArenaAlloc *alloc, SkRasterPipeline *tPipeline, SkRasterPipeline *postPipeline) const override
static sk_sp< SkShader > Create(const SkPoint &start, SkScalar startRadius, const SkPoint &end, SkScalar endRadius, const Descriptor &, const SkMatrix *localMatrix)
bool isOpaque() const override
static void Register(const char name[], Factory)
static constexpr SkScalar kDegenerateThreshold
static bool ValidGradient(const SkColor4f colors[], int count, SkTileMode tileMode, const Interpolation &interpolation)
static sk_sp< SkShader > MakeDegenerateGradient(const SkColor4f colors[], const SkScalar pos[], int colorCount, sk_sp< SkColorSpace > colorSpace, SkTileMode mode)
void flatten(SkWriteBuffer &) const override
void commonAsAGradient(GradientInfo *) const
ShaderType type() const final
static sk_sp< SkShader > MakeTwoPointConical(const SkPoint &start, SkScalar startRadius, const SkPoint &end, SkScalar endRadius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
bool invert(SkMatrix *inverse) const
static const SkMatrix & I()
void append(SkRasterPipelineOp, void *=nullptr)
FlutterSemanticsFlag flags
static const uint8_t buffer[]
bool set(SkScalar r0, SkScalar r1, SkMatrix *matrix)
bool isNativelyFocal() const
bool isWellBehaved() const
bool isFocalOnCircle() const
constexpr float y() const
constexpr float x() const