OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 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 | |
8 #include "SkGradientShader.h" | |
9 #include "SkSVGLinearGradient.h" | |
10 #include "SkSVGRenderContext.h" | |
11 #include "SkSVGStop.h" | |
12 #include "SkSVGValue.h" | |
13 | |
14 SkSVGLinearGradient::SkSVGLinearGradient() : INHERITED(SkSVGTag::kLinearGradient ) {} | |
15 | |
16 void SkSVGLinearGradient::setHref(const SkSVGStringType& href) { | |
17 fHref = std::move(href); | |
18 } | |
19 | |
20 void SkSVGLinearGradient::setX1(const SkSVGLength& x1) { | |
21 fX1 = x1; | |
22 } | |
23 | |
24 void SkSVGLinearGradient::setY1(const SkSVGLength& y1) { | |
25 fY1 = y1; | |
26 } | |
27 | |
28 void SkSVGLinearGradient::setX2(const SkSVGLength& x2) { | |
29 fX2 = x2; | |
30 } | |
31 | |
32 void SkSVGLinearGradient::setY2(const SkSVGLength& y2) { | |
33 fY2 = y2; | |
34 } | |
35 | |
36 void SkSVGLinearGradient::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { | |
37 switch (attr) { | |
38 case SkSVGAttribute::kHref: | |
39 if (const auto* href = v.as<SkSVGStringValue>()) { | |
40 this->setHref(*href); | |
41 } | |
42 break; | |
43 case SkSVGAttribute::kX1: | |
44 if (const auto* x1 = v.as<SkSVGLengthValue>()) { | |
45 this->setX1(*x1); | |
46 } | |
47 break; | |
48 case SkSVGAttribute::kY1: | |
49 if (const auto* y1 = v.as<SkSVGLengthValue>()) { | |
50 this->setY1(*y1); | |
51 } | |
52 break; | |
53 case SkSVGAttribute::kX2: | |
54 if (const auto* x2 = v.as<SkSVGLengthValue>()) { | |
55 this->setX2(*x2); | |
56 } | |
57 break; | |
58 case SkSVGAttribute::kY2: | |
59 if (const auto* y2 = v.as<SkSVGLengthValue>()) { | |
60 this->setY2(*y2); | |
61 } | |
62 break; | |
63 default: | |
64 this->INHERITED::onSetAttribute(attr, v); | |
65 } | |
66 } | |
67 | |
68 // https://www.w3.org/TR/SVG/pservers.html#LinearGradientElementHrefAttribute | |
69 void SkSVGLinearGradient::collectColorStops(const SkSVGRenderContext& ctx, | |
70 SkSTArray<2, SkScalar, true>* pos, | |
71 SkSTArray<2, SkColor, true>* colors) const { | |
72 // Used to resolve percentage offsets. | |
73 const SkSVGLengthContext ltx(SkSize::Make(1, 1)); | |
74 | |
75 for (const auto& child : fChildren) { | |
76 if (child->tag() != SkSVGTag::kStop) { | |
77 continue; | |
78 } | |
79 | |
80 const auto& stop = static_cast<const SkSVGStop&>(*child); | |
81 colors->push_back(SkColorSetA(stop.stopColor(), | |
82 SkScalarRoundToInt(stop.stopOpacity() * 25 5))); | |
83 pos->push_back(SkTPin(ltx.resolve(stop.offset(), SkSVGLengthContext::Len gthType::kOther), | |
84 0.f, 1.f)); | |
85 } | |
86 | |
robertphillips
2016/09/12 19:31:52
Shouldn't this test be more like:
if ((pos->count
f(malita)
2016/09/12 19:52:09
pos->count should always match colors->count becau
| |
87 if (pos->empty() && !fHref.value().isEmpty()) { | |
88 const auto* ref = ctx.findNodeById(fHref); | |
89 if (ref && ref->tag() == SkSVGTag::kLinearGradient) { | |
90 static_cast<const SkSVGLinearGradient*>(ref)->collectColorStops(ctx, pos, colors); | |
91 } | |
92 } | |
93 } | |
94 | |
95 bool SkSVGLinearGradient::onAsPaint(const SkSVGRenderContext& ctx, SkPaint* pain t) const { | |
96 const auto& lctx = ctx.lengthContext(); | |
97 const auto x1 = lctx.resolve(fX1, SkSVGLengthContext::LengthType::kHorizonta l); | |
98 const auto y1 = lctx.resolve(fY1, SkSVGLengthContext::LengthType::kVertical) ; | |
99 const auto x2 = lctx.resolve(fX2, SkSVGLengthContext::LengthType::kHorizonta l); | |
100 const auto y2 = lctx.resolve(fY2, SkSVGLengthContext::LengthType::kVertical) ; | |
101 | |
102 const SkPoint pts[2] = { {x1, y1}, {x2, y2}}; | |
103 SkSTArray<2, SkColor , true> colors; | |
104 SkSTArray<2, SkScalar, true> pos; | |
105 | |
106 this->collectColorStops(ctx, &pos, &colors); | |
107 // TODO: | |
108 // * stop (lazy?) sorting | |
109 // * href loop detection | |
110 // * href attribute inheritance (not just color stops) | |
111 // * spreadMethods support | |
112 // * objectBoundingBox units support | |
113 | |
114 paint->setShader(SkGradientShader::MakeLinear(pts, colors.begin(), pos.begin (), colors.count(), | |
115 SkShader::kClamp_TileMode)); | |
116 return true; | |
117 } | |
OLD | NEW |