Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkLinearGradient.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
23
24#include <cstdint>
25#include <utility>
26
27class SkArenaAlloc;
29enum class SkTileMode;
30
31static SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) {
32 SkVector vec = pts[1] - pts[0];
33 SkScalar mag = vec.length();
34 SkScalar inv = mag ? SkScalarInvert(mag) : 0;
35
36 vec.scale(inv);
37 SkMatrix matrix;
38 matrix.setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
39 matrix.postTranslate(-pts[0].fX, -pts[0].fY);
40 matrix.postScale(inv, inv);
41 return matrix;
42}
43
44///////////////////////////////////////////////////////////////////////////////
45
47 : SkGradientBaseShader(desc, pts_to_unit_matrix(pts)), fStart(pts[0]), fEnd(pts[1]) {}
48
49sk_sp<SkFlattenable> SkLinearGradient::CreateProc(SkReadBuffer& buffer) {
50 DescriptorScope desc;
51 SkMatrix legacyLocalMatrix, *lmPtr = nullptr;
52 if (!desc.unflatten(buffer, &legacyLocalMatrix)) {
53 return nullptr;
54 }
55 if (!legacyLocalMatrix.isIdentity()) {
56 lmPtr = &legacyLocalMatrix;
57 }
58 SkPoint pts[2];
59 pts[0] = buffer.readPoint();
60 pts[1] = buffer.readPoint();
62 desc.fColors,
63 std::move(desc.fColorSpace),
64 desc.fPositions,
65 desc.fColorCount,
66 desc.fTileMode,
67 desc.fInterpolation,
68 lmPtr);
69}
70
72 this->INHERITED::flatten(buffer);
73 buffer.writePoint(fStart);
74 buffer.writePoint(fEnd);
75}
76
78 SkRasterPipeline*) const {
79 // No extra stage needed for linear gradients.
80}
81
83 SkMatrix* localMatrix) const {
84 if (info) {
86 info->fPoint[0] = fStart;
87 info->fPoint[1] = fEnd;
88 }
89 if (localMatrix) {
90 *localMatrix = SkMatrix::I();
91 }
92 return GradientType::kLinear;
93}
94
96 const SkColor4f colors[],
97 sk_sp<SkColorSpace> colorSpace,
98 const SkScalar pos[],
99 int colorCount,
100 SkTileMode mode,
101 const Interpolation& interpolation,
102 const SkMatrix* localMatrix) {
103 if (!pts || !SkIsFinite((pts[1] - pts[0]).length())) {
104 return nullptr;
105 }
106 if (!SkGradientBaseShader::ValidGradient(colors, colorCount, mode, interpolation)) {
107 return nullptr;
108 }
109 if (1 == colorCount) {
110 return SkShaders::Color(colors[0], std::move(colorSpace));
111 }
112 if (localMatrix && !localMatrix->invert(nullptr)) {
113 return nullptr;
114 }
115
116 if (SkScalarNearlyZero((pts[1] - pts[0]).length(),
118 // Degenerate gradient, the only tricky complication is when in clamp mode, the limit of
119 // the gradient approaches two half planes of solid color (first and last). However, they
120 // are divided by the line perpendicular to the start and end point, which becomes undefined
121 // once start and end are exactly the same, so just use the end color for a stable solution.
123 colors, pos, colorCount, std::move(colorSpace), mode);
124 }
125
127 colors, std::move(colorSpace), pos, colorCount, mode, interpolation);
128 return SkLocalMatrixShader::MakeWrapped<SkLinearGradient>(localMatrix, pts, desc);
129}
130
132 const SkColor colors[],
133 const SkScalar pos[],
134 int colorCount,
135 SkTileMode mode,
136 uint32_t flags,
137 const SkMatrix* localMatrix) {
138 SkColorConverter converter(colors, colorCount);
139 return MakeLinear(pts, converter.fColors4f.begin(), nullptr, pos, colorCount, mode, flags,
140 localMatrix);
141}
142
static SkM44 inv(const SkM44 &m)
Definition 3d.cpp:26
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
SkPoint pos
uint32_t SkColor
Definition SkColor.h:37
#define SK_REGISTER_FLATTENABLE(type)
static bool SkIsFinite(T x, Pack... values)
void SkRegisterLinearGradientShaderFlattenable()
static SkMatrix pts_to_unit_matrix(const SkPoint pts[2])
#define SkScalarInvert(x)
Definition SkScalar.h:73
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:101
SkTileMode
Definition SkTileMode.h:13
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
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
SkLinearGradient(const SkPoint pts[2], const Descriptor &)
void flatten(SkWriteBuffer &buffer) const override
void appendGradientStages(SkArenaAlloc *alloc, SkRasterPipeline *tPipeline, SkRasterPipeline *postPipeline) const final
GradientType asGradient(GradientInfo *info, SkMatrix *localMatrix) const override
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
static const SkMatrix & I()
bool isIdentity() const
Definition SkMatrix.h:223
static sk_sp< SkShader > MakeLinear()
float SkScalar
Definition extension.cpp:12
FlutterSemanticsFlag flags
static const uint8_t buffer[]
size_t length
float fX
x-axis value
float length() const
void scale(float scale, SkPoint *dst) const
Definition SkPoint.cpp:17
float fY
y-axis value