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