blob: db103bef59179b41db17496cdf29065135ca1786 [file] [log] [blame]
/*
* 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 SkSVGTypes_DEFINED
#define SkSVGTypes_DEFINED
#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSpan.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkTLazy.h"
using SkSVGColorType = SkColor;
using SkSVGIntegerType = int;
using SkSVGNumberType = SkScalar;
using SkSVGStringType = SkString;
using SkSVGViewBoxType = SkRect;
using SkSVGTransformType = SkMatrix;
using SkSVGPointsType = SkTDArray<SkPoint>;
enum class SkSVGPropertyState {
kUnspecified,
kInherit,
kValue,
};
// https://www.w3.org/TR/SVG11/intro.html#TermProperty
template <typename T, bool kInheritable> class SkSVGProperty {
public:
using ValueT = T;
SkSVGProperty() : fState(SkSVGPropertyState::kUnspecified) {}
explicit SkSVGProperty(SkSVGPropertyState state) : fState(state) {}
explicit SkSVGProperty(const T& value) : fState(SkSVGPropertyState::kValue) {
fValue.set(value);
}
explicit SkSVGProperty(T&& value) : fState(SkSVGPropertyState::kValue) {
fValue.set(std::move(value));
}
template <typename... Args>
void init(Args&&... args) {
fState = SkSVGPropertyState::kValue;
fValue.init(std::forward<Args>(args)...);
}
constexpr bool isInheritable() const { return kInheritable; }
bool isValue() const { return fState == SkSVGPropertyState::kValue; }
T* getMaybeNull() const {
return fValue.getMaybeNull();
}
void set(SkSVGPropertyState state) {
fState = state;
if (fState != SkSVGPropertyState::kValue) {
fValue.reset();
}
}
void set(const T& value) {
fState = SkSVGPropertyState::kValue;
fValue.set(value);
}
void set(T&& value) {
fState = SkSVGPropertyState::kValue;
fValue.set(std::move(value));
}
T* operator->() {
SkASSERT(fState == SkSVGPropertyState::kValue);
SkASSERT(fValue.isValid());
return fValue.get();
}
const T* operator->() const {
SkASSERT(fState == SkSVGPropertyState::kValue);
SkASSERT(fValue.isValid());
return fValue.get();
}
T& operator*() {
SkASSERT(fState == SkSVGPropertyState::kValue);
SkASSERT(fValue.isValid());
return *fValue;
}
const T& operator*() const {
SkASSERT(fState == SkSVGPropertyState::kValue);
SkASSERT(fValue.isValid());
return *fValue;
}
private:
SkSVGPropertyState fState;
SkTLazy<T> fValue;
};
class SkSVGLength {
public:
enum class Unit {
kUnknown,
kNumber,
kPercentage,
kEMS,
kEXS,
kPX,
kCM,
kMM,
kIN,
kPT,
kPC,
};
constexpr SkSVGLength() : fValue(0), fUnit(Unit::kUnknown) {}
explicit constexpr SkSVGLength(SkScalar v, Unit u = Unit::kNumber)
: fValue(v), fUnit(u) {}
SkSVGLength(const SkSVGLength&) = default;
SkSVGLength& operator=(const SkSVGLength&) = default;
bool operator==(const SkSVGLength& other) const {
return fUnit == other.fUnit && fValue == other.fValue;
}
bool operator!=(const SkSVGLength& other) const { return !(*this == other); }
const SkScalar& value() const { return fValue; }
const Unit& unit() const { return fUnit; }
private:
SkScalar fValue;
Unit fUnit;
};
// https://www.w3.org/TR/SVG11/linking.html#IRIReference
class SkSVGIRI {
public:
enum class Type {
kLocal,
kNonlocal,
kDataURI,
};
SkSVGIRI() : fType(Type::kLocal) {}
SkSVGIRI(Type t, const SkSVGStringType& iri) : fType(t), fIRI(iri) {}
Type type() const { return fType; }
const SkSVGStringType& iri() const { return fIRI; }
bool operator==(const SkSVGIRI& other) const {
return fType == other.fType && fIRI == other.fIRI;
}
bool operator!=(const SkSVGIRI& other) const { return !(*this == other); }
private:
Type fType;
SkSVGStringType fIRI;
};
// https://www.w3.org/TR/SVG11/types.html#InterfaceSVGColor
class SkSVGColor {
public:
enum class Type {
kCurrentColor,
kColor,
kICCColor,
};
using Vars = SkSTArray<1, SkString>;
SkSVGColor() : SkSVGColor(SK_ColorBLACK) {}
explicit SkSVGColor(const SkSVGColorType& c) : fType(Type::kColor), fColor(c), fVars(nullptr) {}
explicit SkSVGColor(Type t, Vars&& vars)
: fType(t), fColor(SK_ColorBLACK)
, fVars(vars.empty() ? nullptr : new RefCntVars(std::move(vars))) {}
explicit SkSVGColor(const SkSVGColorType& c, Vars&& vars)
: fType(Type::kColor), fColor(c)
, fVars(vars.empty() ? nullptr : new RefCntVars(std::move(vars))) {}
SkSVGColor(const SkSVGColor&) = default;
SkSVGColor& operator=(const SkSVGColor&) = default;
SkSVGColor(SkSVGColor&&) = default;
SkSVGColor& operator=(SkSVGColor&&) = default;
bool operator==(const SkSVGColor& other) const {
return fType == other.fType && fColor == other.fColor && fVars == other.fVars;
}
bool operator!=(const SkSVGColor& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
SkSpan<const SkString> vars() const {
return fVars ? SkSpan<const SkString>(fVars->fData) : SkSpan<const SkString>();
}
SkSpan<SkString> vars() {
return fVars ? SkSpan<SkString>(fVars->fData) : SkSpan<SkString>();
}
private:
Type fType;
SkSVGColorType fColor;
struct RefCntVars : public SkNVRefCnt<RefCntVars> {
RefCntVars(Vars&& vars) : fData(std::move(vars)) {}
Vars fData;
};
sk_sp<RefCntVars> fVars;
};
class SkSVGPaint {
public:
enum class Type {
kNone,
kColor,
kIRI,
};
SkSVGPaint() : fType(Type::kNone), fColor(SK_ColorBLACK) {}
explicit SkSVGPaint(Type t) : fType(t), fColor(SK_ColorBLACK) {}
explicit SkSVGPaint(SkSVGColor c) : fType(Type::kColor), fColor(std::move(c)) {}
SkSVGPaint(const SkSVGIRI& iri, SkSVGColor fallback_color)
: fType(Type::kIRI), fColor(std::move(fallback_color)), fIRI(iri) {}
SkSVGPaint(const SkSVGPaint&) = default;
SkSVGPaint& operator=(const SkSVGPaint&) = default;
SkSVGPaint(SkSVGPaint&&) = default;
SkSVGPaint& operator=(SkSVGPaint&&) = default;
bool operator==(const SkSVGPaint& other) const {
return fType == other.fType && fColor == other.fColor && fIRI == other.fIRI;
}
bool operator!=(const SkSVGPaint& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkSVGColor& color() const {
SkASSERT(fType == Type::kColor || fType == Type::kIRI);
return fColor;
}
const SkSVGIRI& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
private:
Type fType;
// Logical union.
SkSVGColor fColor;
SkSVGIRI fIRI;
};
// <funciri> | none (used for clip/mask/filter properties)
class SkSVGFuncIRI {
public:
enum class Type {
kNone,
kIRI,
};
SkSVGFuncIRI() : fType(Type::kNone) {}
explicit SkSVGFuncIRI(Type t) : fType(t) {}
explicit SkSVGFuncIRI(SkSVGIRI&& iri) : fType(Type::kIRI), fIRI(std::move(iri)) {}
bool operator==(const SkSVGFuncIRI& other) const {
return fType == other.fType && fIRI == other.fIRI;
}
bool operator!=(const SkSVGFuncIRI& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkSVGIRI& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
private:
Type fType;
SkSVGIRI fIRI;
};
enum class SkSVGLineCap {
kButt,
kRound,
kSquare,
};
class SkSVGLineJoin {
public:
enum class Type {
kMiter,
kRound,
kBevel,
kInherit,
};
constexpr SkSVGLineJoin() : fType(Type::kInherit) {}
constexpr explicit SkSVGLineJoin(Type t) : fType(t) {}
SkSVGLineJoin(const SkSVGLineJoin&) = default;
SkSVGLineJoin& operator=(const SkSVGLineJoin&) = default;
bool operator==(const SkSVGLineJoin& other) const { return fType == other.fType; }
bool operator!=(const SkSVGLineJoin& other) const { return !(*this == other); }
Type type() const { return fType; }
private:
Type fType;
};
class SkSVGSpreadMethod {
public:
// These values must match Skia's SkShader::TileMode enum.
enum class Type {
kPad, // kClamp_TileMode
kRepeat, // kRepeat_TileMode
kReflect, // kMirror_TileMode
};
constexpr SkSVGSpreadMethod() : fType(Type::kPad) {}
constexpr explicit SkSVGSpreadMethod(Type t) : fType(t) {}
SkSVGSpreadMethod(const SkSVGSpreadMethod&) = default;
SkSVGSpreadMethod& operator=(const SkSVGSpreadMethod&) = default;
bool operator==(const SkSVGSpreadMethod& other) const { return fType == other.fType; }
bool operator!=(const SkSVGSpreadMethod& other) const { return !(*this == other); }
Type type() const { return fType; }
private:
Type fType;
};
class SkSVGFillRule {
public:
enum class Type {
kNonZero,
kEvenOdd,
kInherit,
};
constexpr SkSVGFillRule() : fType(Type::kInherit) {}
constexpr explicit SkSVGFillRule(Type t) : fType(t) {}
SkSVGFillRule(const SkSVGFillRule&) = default;
SkSVGFillRule& operator=(const SkSVGFillRule&) = default;
bool operator==(const SkSVGFillRule& other) const { return fType == other.fType; }
bool operator!=(const SkSVGFillRule& other) const { return !(*this == other); }
Type type() const { return fType; }
SkPathFillType asFillType() const {
SkASSERT(fType != Type::kInherit); // should never be called for unresolved values.
return fType == Type::kEvenOdd ? SkPathFillType::kEvenOdd : SkPathFillType::kWinding;
}
private:
Type fType;
};
class SkSVGVisibility {
public:
enum class Type {
kVisible,
kHidden,
kCollapse,
kInherit,
};
constexpr SkSVGVisibility() : fType(Type::kVisible) {}
constexpr explicit SkSVGVisibility(Type t) : fType(t) {}
SkSVGVisibility(const SkSVGVisibility&) = default;
SkSVGVisibility& operator=(const SkSVGVisibility&) = default;
bool operator==(const SkSVGVisibility& other) const { return fType == other.fType; }
bool operator!=(const SkSVGVisibility& other) const { return !(*this == other); }
Type type() const { return fType; }
private:
Type fType;
};
class SkSVGDashArray {
public:
enum class Type {
kNone,
kDashArray,
kInherit,
};
SkSVGDashArray() : fType(Type::kNone) {}
explicit SkSVGDashArray(Type t) : fType(t) {}
explicit SkSVGDashArray(SkTDArray<SkSVGLength>&& dashArray)
: fType(Type::kDashArray)
, fDashArray(std::move(dashArray)) {}
SkSVGDashArray(const SkSVGDashArray&) = default;
SkSVGDashArray& operator=(const SkSVGDashArray&) = default;
bool operator==(const SkSVGDashArray& other) const {
return fType == other.fType && fDashArray == other.fDashArray;
}
bool operator!=(const SkSVGDashArray& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkTDArray<SkSVGLength>& dashArray() const { return fDashArray; }
private:
Type fType;
SkTDArray<SkSVGLength> fDashArray;
};
class SkSVGStopColor {
public:
enum class Type {
kColor,
kCurrentColor,
kICCColor,
kInherit,
};
SkSVGStopColor() : fType(Type::kColor), fColor(SK_ColorBLACK) {}
explicit SkSVGStopColor(Type t) : fType(t), fColor(SK_ColorBLACK) {}
explicit SkSVGStopColor(const SkSVGColorType& c) : fType(Type::kColor), fColor(c) {}
SkSVGStopColor(const SkSVGStopColor&) = default;
SkSVGStopColor& operator=(const SkSVGStopColor&) = default;
bool operator==(const SkSVGStopColor& other) const {
return fType == other.fType && fColor == other.fColor;
}
bool operator!=(const SkSVGStopColor& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
private:
Type fType;
SkSVGColorType fColor;
};
class SkSVGObjectBoundingBoxUnits {
public:
enum class Type {
kUserSpaceOnUse,
kObjectBoundingBox,
};
SkSVGObjectBoundingBoxUnits() : fType(Type::kUserSpaceOnUse) {}
explicit SkSVGObjectBoundingBoxUnits(Type t) : fType(t) {}
bool operator==(const SkSVGObjectBoundingBoxUnits& other) const {
return fType == other.fType;
}
bool operator!=(const SkSVGObjectBoundingBoxUnits& other) const {
return !(*this == other);
}
Type type() const { return fType; }
private:
Type fType;
};
class SkSVGFontFamily {
public:
enum class Type {
kFamily,
kInherit,
};
SkSVGFontFamily() : fType(Type::kInherit) {}
explicit SkSVGFontFamily(const char family[])
: fType(Type::kFamily)
, fFamily(family) {}
bool operator==(const SkSVGFontFamily& other) const {
return fType == other.fType && fFamily == other.fFamily;
}
bool operator!=(const SkSVGFontFamily& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkString& family() const { return fFamily; }
private:
Type fType;
SkString fFamily;
};
class SkSVGFontStyle {
public:
enum class Type {
kNormal,
kItalic,
kOblique,
kInherit,
};
SkSVGFontStyle() : fType(Type::kInherit) {}
explicit SkSVGFontStyle(Type t) : fType(t) {}
bool operator==(const SkSVGFontStyle& other) const {
return fType == other.fType;
}
bool operator!=(const SkSVGFontStyle& other) const { return !(*this == other); }
Type type() const { return fType; }
private:
Type fType;
};
class SkSVGFontSize {
public:
enum class Type {
kLength,
kInherit,
};
SkSVGFontSize() : fType(Type::kInherit), fSize(0) {}
explicit SkSVGFontSize(const SkSVGLength& s)
: fType(Type::kLength)
, fSize(s) {}
bool operator==(const SkSVGFontSize& other) const {
return fType == other.fType && fSize == other.fSize;
}
bool operator!=(const SkSVGFontSize& other) const { return !(*this == other); }
Type type() const { return fType; }
const SkSVGLength& size() const { return fSize; }
private:
Type fType;
SkSVGLength fSize;
};
class SkSVGFontWeight {
public:
enum class Type {
k100,
k200,
k300,
k400,
k500,
k600,
k700,
k800,
k900,
kNormal,
kBold,
kBolder,
kLighter,
kInherit,
};
SkSVGFontWeight() : fType(Type::kInherit) {}
explicit SkSVGFontWeight(Type t) : fType(t) {}
bool operator==(const SkSVGFontWeight& other) const {
return fType == other.fType;
}
bool operator!=(const SkSVGFontWeight& other) const { return !(*this == other); }
Type type() const { return fType; }
private:
Type fType;
};
struct SkSVGPreserveAspectRatio {
enum Align : uint8_t {
// These values are chosen such that bits [0,1] encode X alignment, and
// bits [2,3] encode Y alignment.
kXMinYMin = 0x00,
kXMidYMin = 0x01,
kXMaxYMin = 0x02,
kXMinYMid = 0x04,
kXMidYMid = 0x05,
kXMaxYMid = 0x06,
kXMinYMax = 0x08,
kXMidYMax = 0x09,
kXMaxYMax = 0x0a,
kNone = 0x10,
};
enum Scale {
kMeet,
kSlice,
};
Align fAlign = kXMidYMid;
Scale fScale = kMeet;
};
class SkSVGTextAnchor {
public:
enum class Type {
kStart,
kMiddle,
kEnd,
kInherit,
};
SkSVGTextAnchor() : fType(Type::kInherit) {}
explicit SkSVGTextAnchor(Type t) : fType(t) {}
bool operator==(const SkSVGTextAnchor& other) const {
return fType == other.fType;
}
bool operator!=(const SkSVGTextAnchor& other) const { return !(*this == other); }
Type type() const { return fType; }
private:
Type fType;
};
// https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveInAttribute
class SkSVGFeInputType {
public:
enum class Type {
kSourceGraphic,
kSourceAlpha,
kBackgroundImage,
kBackgroundAlpha,
kFillPaint,
kStrokePaint,
kFilterPrimitiveReference,
kUnspecified,
};
SkSVGFeInputType() : fType(Type::kUnspecified) {}
explicit SkSVGFeInputType(Type t) : fType(t) {}
explicit SkSVGFeInputType(const SkSVGStringType& id)
: fType(Type::kFilterPrimitiveReference), fId(id) {}
bool operator==(const SkSVGFeInputType& other) const {
return fType == other.fType && fId == other.fId;
}
bool operator!=(const SkSVGFeInputType& other) const { return !(*this == other); }
const SkString& id() const {
SkASSERT(fType == Type::kFilterPrimitiveReference);
return fId;
}
Type type() const { return fType; }
private:
Type fType;
SkString fId;
};
enum class SkSVGFeColorMatrixType {
kMatrix,
kSaturate,
kHueRotate,
kLuminanceToAlpha,
};
using SkSVGFeColorMatrixValues = SkTDArray<SkSVGNumberType>;
enum class SkSVGFeCompositeOperator {
kOver,
kIn,
kOut,
kAtop,
kXor,
kArithmetic,
};
class SkSVGFeTurbulenceBaseFrequency {
public:
SkSVGFeTurbulenceBaseFrequency() : fFreqX(0), fFreqY(0) {}
SkSVGFeTurbulenceBaseFrequency(SkSVGNumberType freqX, SkSVGNumberType freqY)
: fFreqX(freqX), fFreqY(freqY) {}
SkSVGNumberType freqX() const { return fFreqX; }
SkSVGNumberType freqY() const { return fFreqY; }
private:
SkSVGNumberType fFreqX;
SkSVGNumberType fFreqY;
};
struct SkSVGFeTurbulenceType {
enum Type {
kFractalNoise,
kTurbulence,
};
Type fType;
SkSVGFeTurbulenceType() : fType(kTurbulence) {}
explicit SkSVGFeTurbulenceType(Type type) : fType(type) {}
};
enum class SkSVGXmlSpace {
kDefault,
kPreserve,
};
enum class SkSVGColorspace {
kAuto,
kSRGB,
kLinearRGB,
};
// https://www.w3.org/TR/SVG11/painting.html#DisplayProperty
enum class SkSVGDisplay {
kInline,
kNone,
};
#endif // SkSVGTypes_DEFINED