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