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 #ifndef SkSVGAttributeParser_DEFINED 9 #define SkSVGAttributeParser_DEFINED 10 11 #include "include/core/SkColor.h" 12 #include "include/core/SkScalar.h" 13 #include "include/core/SkTypes.h" 14 #include "include/private/base/SkNoncopyable.h" 15 #include "modules/svg/include/SkSVGTypes.h" 16 17 #include "src/base/SkTLazy.h" 18 19 #include <cstdint> 20 #include <cstring> 21 #include <tuple> 22 #include <vector> 23 24 class SkMatrix; 25 class SkString; 26 27 class SkSVGAttributeParser : public SkNoncopyable { 28 public: 29 SkSVGAttributeParser(const char[]); 30 31 bool parseInteger(SkSVGIntegerType*); 32 bool parseViewBox(SkSVGViewBoxType*); 33 bool parsePreserveAspectRatio(SkSVGPreserveAspectRatio*); 34 35 // TODO: Migrate all parse*() functions to this style (and delete the old version) 36 // so they can be used by parse<T>(): parse(SkSVGIntegerType * v)37 bool parse(SkSVGIntegerType* v) { return parseInteger(v); } 38 39 template <typename T> using ParseResult = SkTLazy<T>; 40 parse(const char * value)41 template <typename T> static ParseResult<T> parse(const char* value) { 42 ParseResult<T> result; 43 T parsedValue; 44 if (SkSVGAttributeParser(value).parse(&parsedValue)) { 45 result.set(std::move(parsedValue)); 46 } 47 return result; 48 } 49 50 template <typename T> parse(const char * expectedName,const char * name,const char * value)51 static ParseResult<T> parse(const char* expectedName, 52 const char* name, 53 const char* value) { 54 if (!strcmp(name, expectedName)) { 55 return parse<T>(value); 56 } 57 58 return ParseResult<T>(); 59 } 60 61 template <typename PropertyT> parseProperty(const char * expectedName,const char * name,const char * value)62 static ParseResult<PropertyT> parseProperty(const char* expectedName, 63 const char* name, 64 const char* value) { 65 if (strcmp(name, expectedName) != 0) { 66 return ParseResult<PropertyT>(); 67 } 68 69 if (!strcmp(value, "inherit")) { 70 PropertyT result(SkSVGPropertyState::kInherit); 71 return ParseResult<PropertyT>(&result); 72 } 73 74 auto pr = parse<typename PropertyT::ValueT>(value); 75 if (pr.isValid()) { 76 PropertyT result(*pr); 77 return ParseResult<PropertyT>(&result); 78 } 79 80 return ParseResult<PropertyT>(); 81 } 82 83 private: 84 class RestoreCurPos { 85 public: RestoreCurPos(SkSVGAttributeParser * self)86 explicit RestoreCurPos(SkSVGAttributeParser* self) 87 : fSelf(self), fCurPos(self->fCurPos) {} 88 ~RestoreCurPos()89 ~RestoreCurPos() { 90 if (fSelf) { 91 fSelf->fCurPos = this->fCurPos; 92 } 93 } 94 clear()95 void clear() { fSelf = nullptr; } 96 private: 97 SkSVGAttributeParser* fSelf; 98 const char* fCurPos; 99 100 RestoreCurPos( const RestoreCurPos&) = delete; 101 RestoreCurPos& operator=(const RestoreCurPos&) = delete; 102 }; 103 104 // Stack-only 105 void* operator new(size_t) = delete; 106 void* operator new(size_t, void*) = delete; 107 108 template <typename T> 109 bool parse(T*); 110 111 template <typename F> 112 bool advanceWhile(F func); 113 114 bool matchStringToken(const char* token, const char** newPos = nullptr) const; 115 bool matchHexToken(const char** newPos) const; 116 117 bool parseWSToken(); 118 bool parseEOSToken(); 119 bool parseSepToken(); 120 bool parseCommaWspToken(); 121 bool parseExpectedStringToken(const char*); 122 bool parseScalarToken(SkScalar*); 123 bool parseInt32Token(int32_t*); 124 bool parseEscape(SkUnichar*); 125 bool parseIdentToken(SkString*); 126 bool parseLengthUnitToken(SkSVGLength::Unit*); 127 bool parseNamedColorToken(SkColor*); 128 bool parseHexColorToken(SkColor*); 129 bool parseColorComponentScalarToken(int32_t*); 130 bool parseColorComponentIntegralToken(int32_t*); 131 bool parseColorComponentFractionalToken(int32_t*); 132 bool parseColorComponentToken(int32_t*); 133 bool parseColorToken(SkColor*); 134 bool parseRGBColorToken(SkColor*); 135 bool parseRGBAColorToken(SkColor*); 136 bool parseSVGColor(SkSVGColor*, SkSVGColor::Vars&&); 137 bool parseSVGColorType(SkSVGColorType*); 138 bool parseFuncIRI(SkSVGFuncIRI*); 139 140 // Transform helpers 141 bool parseMatrixToken(SkMatrix*); 142 bool parseTranslateToken(SkMatrix*); 143 bool parseScaleToken(SkMatrix*); 144 bool parseRotateToken(SkMatrix*); 145 bool parseSkewXToken(SkMatrix*); 146 bool parseSkewYToken(SkMatrix*); 147 148 // Parses a sequence of 'WS* <prefix> WS* (<nested>)', where the nested sequence 149 // is handled by the passed functor. 150 template <typename Func, typename T> 151 bool parseParenthesized(const char* prefix, Func, T* result); 152 153 template <typename T> 154 bool parseList(std::vector<T>*); 155 156 template <typename T, typename TArray> parseEnumMap(const TArray & arr,T * result)157 bool parseEnumMap(const TArray& arr, T* result) { 158 for (size_t i = 0; i < std::size(arr); ++i) { 159 if (this->parseExpectedStringToken(std::get<0>(arr[i]))) { 160 *result = std::get<1>(arr[i]); 161 return true; 162 } 163 } 164 return false; 165 } 166 167 // The current position in the input string. 168 const char* fCurPos; 169 const char* fEndPos; 170 171 using INHERITED = SkNoncopyable; 172 }; 173 174 #endif // SkSVGAttributeParser_DEFINED 175