• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 "include/core/SkColorFilter.h"
9 #include "include/effects/SkImageFilters.h"
10 #include "include/private/SkColorData.h"
11 #include "modules/svg/include/SkSVGAttributeParser.h"
12 #include "modules/svg/include/SkSVGFeColorMatrix.h"
13 #include "modules/svg/include/SkSVGFilterContext.h"
14 #include "modules/svg/include/SkSVGRenderContext.h"
15 #include "modules/svg/include/SkSVGValue.h"
16 
parseAndSetAttribute(const char * name,const char * value)17 bool SkSVGFeColorMatrix::parseAndSetAttribute(const char* name, const char* value) {
18     return INHERITED::parseAndSetAttribute(name, value) ||
19            this->setType(
20                    SkSVGAttributeParser::parse<SkSVGFeColorMatrixType>("type", name, value)) ||
21            this->setValues(
22                    SkSVGAttributeParser::parse<SkSVGFeColorMatrixValues>("values", name, value));
23 }
24 
makeMatrixForType() const25 SkColorMatrix SkSVGFeColorMatrix::makeMatrixForType() const {
26     if (fValues.empty() && fType != SkSVGFeColorMatrixType::kLuminanceToAlpha) {
27         return SkColorMatrix();
28     }
29 
30     switch (fType) {
31         case SkSVGFeColorMatrixType::kMatrix: {
32             if (fValues.size() < 20) {
33                 return SkColorMatrix();
34             }
35             SkColorMatrix m;
36             m.setRowMajor(this->fValues.begin());
37             return m;
38         }
39         case SkSVGFeColorMatrixType::kSaturate:
40             return MakeSaturate(!fValues.empty() ? fValues[0] : 1);
41         case SkSVGFeColorMatrixType::kHueRotate:
42             return MakeHueRotate(!fValues.empty() ? fValues[0] : 0);
43         case SkSVGFeColorMatrixType::kLuminanceToAlpha:
44             return MakeLuminanceToAlpha();
45     }
46 
47     SkUNREACHABLE;
48 }
49 
MakeSaturate(SkSVGNumberType s)50 SkColorMatrix SkSVGFeColorMatrix::MakeSaturate(SkSVGNumberType s) {
51     SkColorMatrix m;
52     m.setSaturation(s);
53     return m;
54 }
55 
MakeHueRotate(SkSVGNumberType degrees)56 SkColorMatrix SkSVGFeColorMatrix::MakeHueRotate(SkSVGNumberType degrees) {
57     const SkScalar theta = SkDegreesToRadians(degrees);
58     const SkSVGNumberType c = SkScalarCos(theta);
59     const SkSVGNumberType s = SkScalarSin(theta);
60     return SkColorMatrix(
61         0.213f + c* 0.787f + s*-0.213f,
62         0.715f + c*-0.715f + s*-0.715f,
63         0.072f + c*-0.072f + s* 0.928f,
64         0,
65         0,
66 
67         0.213f + c*-0.213f + s* 0.143f,
68         0.715f + c* 0.285f + s* 0.140f,
69         0.072f + c*-0.072f + s*-0.283f,
70         0,
71         0,
72 
73         0.213f + c*-0.213f + s*-0.787f,
74         0.715f + c*-0.715f + s* 0.715f,
75         0.072f + c* 0.928f + s* 0.072f,
76         0,
77         0,
78 
79         0,0,0,1,0
80     );
81 }
82 
MakeLuminanceToAlpha()83 SkColorMatrix SkSVGFeColorMatrix::MakeLuminanceToAlpha() {
84     return SkColorMatrix(
85         0, 0, 0, 0, 0,
86         0, 0, 0, 0, 0,
87         0, 0, 0, 0, 0,
88         SK_LUM_COEFF_R, SK_LUM_COEFF_G, SK_LUM_COEFF_B, 0, 0
89     );
90 }
91 
onMakeImageFilter(const SkSVGRenderContext & ctx,const SkSVGFilterContext & fctx) const92 sk_sp<SkImageFilter> SkSVGFeColorMatrix::onMakeImageFilter(const SkSVGRenderContext& ctx,
93                                                            const SkSVGFilterContext& fctx) const {
94     return SkImageFilters::ColorFilter(
95             SkColorFilters::Matrix(makeMatrixForType()),
96             fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx, fctx)),
97             this->resolveFilterSubregion(ctx, fctx));
98 }
99 
parse(SkSVGFeColorMatrixValues * values)100 template <> bool SkSVGAttributeParser::parse(SkSVGFeColorMatrixValues* values) {
101     SkSVGNumberType value;
102     if (!this->parse(&value)) {
103         return false;
104     }
105 
106     values->push_back(value);
107     while (true) {
108         if (!this->parse(&value) || values->size() >= 20) {
109             break;
110         }
111         values->push_back(value);
112     }
113 
114     return this->parseEOSToken();
115 }
116 
parse(SkSVGFeColorMatrixType * type)117 template <> bool SkSVGAttributeParser::parse(SkSVGFeColorMatrixType* type) {
118     static constexpr std::tuple<const char*, SkSVGFeColorMatrixType> gTypeMap[] = {
119             {"matrix", SkSVGFeColorMatrixType::kMatrix},
120             {"saturate", SkSVGFeColorMatrixType::kSaturate},
121             {"hueRotate", SkSVGFeColorMatrixType::kHueRotate},
122             {"luminanceToAlpha", SkSVGFeColorMatrixType::kLuminanceToAlpha},
123     };
124 
125     return this->parseEnumMap(gTypeMap, type) && this->parseEOSToken();
126 }
127