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/SkNoncopyable.h" 14 #include "modules/svg/include/SkSVGTypes.h" 15 #include "src/core/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 // Stack-only 75 void* operator new(size_t) = delete; 76 void* operator new(size_t, void*) = delete; 77 78 template <typename T> 79 bool parse(T*); 80 81 template <typename F> 82 bool advanceWhile(F func); 83 84 bool matchStringToken(const char* token, const char** newPos = nullptr) const; 85 86 bool parseWSToken(); 87 bool parseEOSToken(); 88 bool parseSepToken(); 89 bool parseCommaWspToken(); 90 bool parseExpectedStringToken(const char*); 91 bool parseScalarToken(SkScalar*); 92 bool parseInt32Token(int32_t*); 93 bool parseHexToken(uint32_t*); 94 bool parseLengthUnitToken(SkSVGLength::Unit*); 95 bool parseNamedColorToken(SkColor*); 96 bool parseHexColorToken(SkColor*); 97 bool parseColorComponentToken(int32_t*); 98 bool parseRGBColorToken(SkColor*); 99 bool parseFuncIRI(SkSVGFuncIRI*); 100 101 // Transform helpers 102 bool parseMatrixToken(SkMatrix*); 103 bool parseTranslateToken(SkMatrix*); 104 bool parseScaleToken(SkMatrix*); 105 bool parseRotateToken(SkMatrix*); 106 bool parseSkewXToken(SkMatrix*); 107 bool parseSkewYToken(SkMatrix*); 108 109 // Parses a sequence of 'WS* <prefix> WS* (<nested>)', where the nested sequence 110 // is handled by the passed functor. 111 template <typename Func, typename T> 112 bool parseParenthesized(const char* prefix, Func, T* result); 113 114 template <typename T> 115 bool parseList(std::vector<T>*); 116 117 template <typename T, typename TArray> parseEnumMap(const TArray & arr,T * result)118 bool parseEnumMap(const TArray& arr, T* result) { 119 for (size_t i = 0; i < SK_ARRAY_COUNT(arr); ++i) { 120 if (this->parseExpectedStringToken(std::get<0>(arr[i]))) { 121 *result = std::get<1>(arr[i]); 122 return true; 123 } 124 } 125 return false; 126 } 127 128 // The current position in the input string. 129 const char* fCurPos; 130 131 using INHERITED = SkNoncopyable; 132 }; 133 134 #endif // SkSVGAttributeParser_DEFINED 135