2022-10-03 16:25:42 +00:00
|
|
|
#ifndef PROPERTY_H
|
|
|
|
#define PROPERTY_H
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <array>
|
|
|
|
|
|
|
|
namespace lunasvg {
|
|
|
|
|
|
|
|
enum class Display
|
|
|
|
{
|
|
|
|
Inline,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class Visibility
|
|
|
|
{
|
|
|
|
Visible,
|
|
|
|
Hidden
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class Overflow
|
|
|
|
{
|
|
|
|
Visible,
|
|
|
|
Hidden
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class LineCap
|
|
|
|
{
|
|
|
|
Butt,
|
|
|
|
Round,
|
|
|
|
Square
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class LineJoin
|
|
|
|
{
|
|
|
|
Miter,
|
|
|
|
Round,
|
|
|
|
Bevel
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class WindRule
|
|
|
|
{
|
|
|
|
NonZero,
|
|
|
|
EvenOdd
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class Units
|
|
|
|
{
|
|
|
|
UserSpaceOnUse,
|
|
|
|
ObjectBoundingBox
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class SpreadMethod
|
|
|
|
{
|
|
|
|
Pad,
|
|
|
|
Reflect,
|
|
|
|
Repeat
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class MarkerUnits
|
|
|
|
{
|
|
|
|
StrokeWidth,
|
|
|
|
UserSpaceOnUse
|
|
|
|
};
|
|
|
|
|
|
|
|
class Color
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Color() = default;
|
2022-10-16 10:31:43 +00:00
|
|
|
explicit Color(uint32_t value) : m_value(value) {}
|
|
|
|
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : m_value(a << 24 | r << 16 | g << 8 | b) {}
|
2022-10-03 16:25:42 +00:00
|
|
|
|
2022-10-16 10:31:43 +00:00
|
|
|
uint8_t alpha() const { return (m_value >> 24) & 0xff; }
|
|
|
|
uint8_t red() const { return (m_value >> 16) & 0xff; }
|
|
|
|
uint8_t green() const { return (m_value >> 8) & 0xff; }
|
|
|
|
uint8_t blue() const { return (m_value >> 0) & 0xff; }
|
|
|
|
|
|
|
|
uint32_t value() const { return m_value; }
|
|
|
|
|
|
|
|
Color& combine(double opacity);
|
|
|
|
Color combined(double opacity) const;
|
|
|
|
|
|
|
|
bool isNone() const { return m_value == 0; }
|
2022-10-03 16:25:42 +00:00
|
|
|
|
|
|
|
static const Color Black;
|
|
|
|
static const Color White;
|
|
|
|
static const Color Transparent;
|
|
|
|
|
2022-10-16 10:31:43 +00:00
|
|
|
private:
|
|
|
|
uint32_t m_value{0};
|
2022-10-03 16:25:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Paint
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Paint() = default;
|
|
|
|
Paint(const Color& color);
|
|
|
|
Paint(const std::string& ref, const Color& color);
|
|
|
|
|
|
|
|
const Color& color() const { return m_color; }
|
|
|
|
const std::string& ref() const { return m_ref; }
|
|
|
|
bool isNone() const { return m_ref.empty() && m_color.isNone(); }
|
|
|
|
|
|
|
|
public:
|
|
|
|
std::string m_ref;
|
|
|
|
Color m_color{Color::Transparent};
|
|
|
|
};
|
|
|
|
|
|
|
|
class Point
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Point() = default;
|
|
|
|
Point(double x, double y);
|
|
|
|
|
|
|
|
public:
|
|
|
|
double x{0};
|
|
|
|
double y{0};
|
|
|
|
};
|
|
|
|
|
|
|
|
using PointList = std::vector<Point>;
|
|
|
|
|
|
|
|
class Box;
|
|
|
|
|
|
|
|
class Rect
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Rect() = default;
|
|
|
|
Rect(double x, double y, double w, double h);
|
|
|
|
Rect(const Box& box);
|
|
|
|
|
|
|
|
Rect operator&(const Rect& rect) const;
|
|
|
|
Rect operator|(const Rect& rect) const;
|
|
|
|
|
|
|
|
Rect& intersect(const Rect& rect);
|
|
|
|
Rect& unite(const Rect& rect);
|
|
|
|
|
|
|
|
bool empty() const { return w <= 0.0 || h <= 0.0; }
|
|
|
|
bool valid() const { return w >= 0.0 && h >= 0.0; }
|
|
|
|
|
|
|
|
static const Rect Empty;
|
|
|
|
static const Rect Invalid;
|
|
|
|
|
|
|
|
public:
|
|
|
|
double x{0};
|
|
|
|
double y{0};
|
|
|
|
double w{0};
|
|
|
|
double h{0};
|
|
|
|
};
|
|
|
|
|
|
|
|
class Matrix;
|
|
|
|
|
|
|
|
class Transform
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Transform() = default;
|
|
|
|
Transform(double m00, double m10, double m01, double m11, double m02, double m12);
|
|
|
|
Transform(const Matrix& matrix);
|
|
|
|
|
|
|
|
Transform inverted() const;
|
|
|
|
Transform operator*(const Transform& transform) const;
|
|
|
|
Transform& operator*=(const Transform& transform);
|
|
|
|
|
|
|
|
Transform& premultiply(const Transform& transform);
|
|
|
|
Transform& postmultiply(const Transform& transform);
|
|
|
|
Transform& rotate(double angle);
|
|
|
|
Transform& rotate(double angle, double cx, double cy);
|
|
|
|
Transform& scale(double sx, double sy);
|
|
|
|
Transform& shear(double shx, double shy);
|
|
|
|
Transform& translate(double tx, double ty);
|
|
|
|
Transform& transform(double m00, double m10, double m01, double m11, double m02, double m12);
|
|
|
|
Transform& identity();
|
|
|
|
Transform& invert();
|
|
|
|
|
|
|
|
void map(double x, double y, double* _x, double* _y) const;
|
|
|
|
Point map(double x, double y) const;
|
|
|
|
Point map(const Point& point) const;
|
|
|
|
Rect map(const Rect& rect) const;
|
|
|
|
|
|
|
|
static Transform rotated(double angle);
|
|
|
|
static Transform rotated(double angle, double cx, double cy);
|
|
|
|
static Transform scaled(double sx, double sy);
|
|
|
|
static Transform sheared(double shx, double shy);
|
|
|
|
static Transform translated(double tx, double ty);
|
|
|
|
|
|
|
|
public:
|
|
|
|
double m00{1};
|
|
|
|
double m10{0};
|
|
|
|
double m01{0};
|
|
|
|
double m11{1};
|
|
|
|
double m02{0};
|
|
|
|
double m12{0};
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class PathCommand
|
|
|
|
{
|
|
|
|
MoveTo,
|
|
|
|
LineTo,
|
|
|
|
CubicTo,
|
|
|
|
Close
|
|
|
|
};
|
|
|
|
|
|
|
|
class Path
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Path() = default;
|
|
|
|
|
|
|
|
void moveTo(double x, double y);
|
|
|
|
void lineTo(double x, double y);
|
|
|
|
void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
|
|
|
void close();
|
|
|
|
void reset();
|
|
|
|
bool empty() const;
|
|
|
|
|
|
|
|
void quadTo(double cx, double cy, double x1, double y1, double x2, double y2);
|
|
|
|
void arcTo(double cx, double cy, double rx, double ry, double xAxisRotation, bool largeArcFlag, bool sweepFlag, double x, double y);
|
|
|
|
|
|
|
|
void ellipse(double cx, double cy, double rx, double ry);
|
|
|
|
void rect(double x, double y, double w, double h, double rx, double ry);
|
|
|
|
|
|
|
|
Rect box() const;
|
|
|
|
|
|
|
|
const std::vector<PathCommand>& commands() const { return m_commands; }
|
|
|
|
const std::vector<Point>& points() const { return m_points; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::vector<PathCommand> m_commands;
|
|
|
|
std::vector<Point> m_points;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PathIterator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PathIterator(const Path& path);
|
|
|
|
|
|
|
|
PathCommand currentSegment(std::array<Point, 3>& points) const;
|
|
|
|
bool isDone() const;
|
|
|
|
void next();
|
|
|
|
|
|
|
|
private:
|
|
|
|
mutable Point m_startPoint;
|
|
|
|
const std::vector<PathCommand>& m_commands;
|
|
|
|
const Point* m_points{nullptr};
|
|
|
|
unsigned int m_index{0};
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class LengthUnits
|
|
|
|
{
|
|
|
|
Unknown,
|
|
|
|
Number,
|
|
|
|
Px,
|
|
|
|
Pt,
|
|
|
|
Pc,
|
|
|
|
In,
|
|
|
|
Cm,
|
|
|
|
Mm,
|
|
|
|
Ex,
|
|
|
|
Em,
|
|
|
|
Percent
|
|
|
|
};
|
|
|
|
|
|
|
|
enum LengthMode
|
|
|
|
{
|
|
|
|
Width,
|
|
|
|
Height,
|
|
|
|
Both
|
|
|
|
};
|
|
|
|
|
|
|
|
class Element;
|
|
|
|
|
|
|
|
class Length
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Length() = default;
|
|
|
|
Length(double value);
|
|
|
|
Length(double value, LengthUnits units);
|
|
|
|
|
|
|
|
double value(double max) const;
|
|
|
|
double value(const Element* element, LengthMode mode) const;
|
|
|
|
|
|
|
|
bool isValid() const { return m_units != LengthUnits::Unknown; }
|
|
|
|
bool isZero() const { return m_value == 0.0; }
|
|
|
|
bool isRelative() const { return m_units == LengthUnits::Percent || m_units == LengthUnits::Em || m_units == LengthUnits::Ex; }
|
|
|
|
|
|
|
|
static const Length Unknown;
|
|
|
|
static const Length Zero;
|
|
|
|
static const Length One;
|
2023-01-06 10:28:43 +00:00
|
|
|
static const Length Three;
|
2022-10-03 16:25:42 +00:00
|
|
|
static const Length HundredPercent;
|
|
|
|
static const Length FiftyPercent;
|
|
|
|
static const Length OneTwentyPercent;
|
|
|
|
static const Length MinusTenPercent;
|
|
|
|
|
|
|
|
private:
|
|
|
|
double m_value{0};
|
|
|
|
LengthUnits m_units{LengthUnits::Px};
|
|
|
|
};
|
|
|
|
|
|
|
|
using LengthList = std::vector<Length>;
|
|
|
|
|
|
|
|
class LengthContext
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
LengthContext(const Element* element);
|
|
|
|
LengthContext(const Element* element, Units units);
|
|
|
|
|
|
|
|
double valueForLength(const Length& length, LengthMode mode) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Element* m_element{nullptr};
|
|
|
|
Units m_units{Units::UserSpaceOnUse};
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class Align
|
|
|
|
{
|
|
|
|
None,
|
|
|
|
xMinYMin,
|
|
|
|
xMidYMin,
|
|
|
|
xMaxYMin,
|
|
|
|
xMinYMid,
|
|
|
|
xMidYMid,
|
|
|
|
xMaxYMid,
|
|
|
|
xMinYMax,
|
|
|
|
xMidYMax,
|
|
|
|
xMaxYMax
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class MeetOrSlice
|
|
|
|
{
|
|
|
|
Meet,
|
|
|
|
Slice
|
|
|
|
};
|
|
|
|
|
|
|
|
class PreserveAspectRatio
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PreserveAspectRatio() = default;
|
|
|
|
PreserveAspectRatio(Align align, MeetOrSlice scale);
|
|
|
|
|
|
|
|
Transform getMatrix(double width, double height, const Rect& viewBox) const;
|
|
|
|
Rect getClip(double width, double height, const Rect& viewBox) const;
|
|
|
|
|
|
|
|
Align align() const { return m_align; }
|
|
|
|
MeetOrSlice scale() const { return m_scale; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Align m_align{Align::xMidYMid};
|
|
|
|
MeetOrSlice m_scale{MeetOrSlice::Meet};
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class MarkerOrient
|
|
|
|
{
|
|
|
|
Auto,
|
|
|
|
Angle
|
|
|
|
};
|
|
|
|
|
|
|
|
class Angle
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Angle() = default;
|
|
|
|
Angle(MarkerOrient type);
|
|
|
|
Angle(double value, MarkerOrient type);
|
|
|
|
|
|
|
|
double value() const { return m_value; }
|
|
|
|
MarkerOrient type() const { return m_type; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
double m_value{0};
|
|
|
|
MarkerOrient m_type{MarkerOrient::Angle};
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace lunasvg
|
|
|
|
|
|
|
|
#endif // PROPERTY_H
|