matterbridge/vendor/github.com/Benau/go_rlottie/vector_vpath.h

286 lines
8.9 KiB
C
Raw Normal View History

/*
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VPATH_H
#define VPATH_H
#include <vector>
#include "vector_vcowptr.h"
#include "vector_vmatrix.h"
#include "vector_vpoint.h"
#include "vector_vrect.h"
V_BEGIN_NAMESPACE
struct VPathData;
class VPath {
public:
enum class Direction { CCW, CW };
enum class Element : uchar { MoveTo, LineTo, CubicTo, Close };
bool empty() const;
bool null() const;
void moveTo(const VPointF &p);
void moveTo(float x, float y);
void lineTo(const VPointF &p);
void lineTo(float x, float y);
void cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e);
void cubicTo(float c1x, float c1y, float c2x, float c2y, float ex,
float ey);
void arcTo(const VRectF &rect, float startAngle, float sweepLength,
bool forceMoveTo);
void close();
void reset();
void reserve(size_t pts, size_t elms);
size_t segments() const;
void addCircle(float cx, float cy, float radius,
VPath::Direction dir = Direction::CW);
void addOval(const VRectF &rect, VPath::Direction dir = Direction::CW);
void addRoundRect(const VRectF &rect, float rx, float ry,
VPath::Direction dir = Direction::CW);
void addRoundRect(const VRectF &rect, float roundness,
VPath::Direction dir = Direction::CW);
void addRect(const VRectF &rect, VPath::Direction dir = Direction::CW);
void addPolystar(float points, float innerRadius, float outerRadius,
float innerRoundness, float outerRoundness,
float startAngle, float cx, float cy,
VPath::Direction dir = Direction::CW);
void addPolygon(float points, float radius, float roundness,
float startAngle, float cx, float cy,
VPath::Direction dir = Direction::CW);
void addPath(const VPath &path);
void addPath(const VPath &path, const VMatrix &m);
void transform(const VMatrix &m);
float length() const;
const std::vector<VPath::Element> &elements() const;
const std::vector<VPointF> & points() const;
void clone(const VPath &srcPath);
bool unique() const { return d.unique();}
size_t refCount() const { return d.refCount();}
private:
struct VPathData {
bool empty() const { return m_elements.empty(); }
bool null() const { return empty() && !m_elements.capacity();}
void moveTo(float x, float y);
void lineTo(float x, float y);
void cubicTo(float cx1, float cy1, float cx2, float cy2, float ex, float ey);
void close();
void reset();
void reserve(size_t, size_t);
void checkNewSegment();
size_t segments() const;
void transform(const VMatrix &m);
float length() const;
void addRoundRect(const VRectF &, float, float, VPath::Direction);
void addRoundRect(const VRectF &, float, VPath::Direction);
void addRect(const VRectF &, VPath::Direction);
void arcTo(const VRectF &, float, float, bool);
void addCircle(float, float, float, VPath::Direction);
void addOval(const VRectF &, VPath::Direction);
void addPolystar(float points, float innerRadius, float outerRadius,
float innerRoundness, float outerRoundness,
float startAngle, float cx, float cy,
VPath::Direction dir = Direction::CW);
void addPolygon(float points, float radius, float roundness,
float startAngle, float cx, float cy,
VPath::Direction dir = Direction::CW);
void addPath(const VPathData &path, const VMatrix *m = nullptr);
void clone(const VPath::VPathData &o) { *this = o;}
const std::vector<VPath::Element> &elements() const
{
return m_elements;
}
const std::vector<VPointF> &points() const { return m_points; }
std::vector<VPointF> m_points;
std::vector<VPath::Element> m_elements;
size_t m_segments;
VPointF mStartPoint;
mutable float mLength{0};
mutable bool mLengthDirty{true};
bool mNewSegment;
};
vcow_ptr<VPathData> d;
};
inline bool VPath::empty() const
{
return d->empty();
}
/*
* path is empty as well as null(no memory for data allocated yet).
*/
inline bool VPath::null() const
{
return d->null();
}
inline void VPath::moveTo(const VPointF &p)
{
d.write().moveTo(p.x(), p.y());
}
inline void VPath::lineTo(const VPointF &p)
{
d.write().lineTo(p.x(), p.y());
}
inline void VPath::close()
{
d.write().close();
}
inline void VPath::reset()
{
d.write().reset();
}
inline void VPath::reserve(size_t pts, size_t elms)
{
d.write().reserve(pts, elms);
}
inline size_t VPath::segments() const
{
return d->segments();
}
inline float VPath::length() const
{
return d->length();
}
inline void VPath::cubicTo(const VPointF &c1, const VPointF &c2,
const VPointF &e)
{
d.write().cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
}
inline void VPath::lineTo(float x, float y)
{
d.write().lineTo(x, y);
}
inline void VPath::moveTo(float x, float y)
{
d.write().moveTo(x, y);
}
inline void VPath::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex,
float ey)
{
d.write().cubicTo(c1x, c1y, c2x, c2y, ex, ey);
}
inline void VPath::transform(const VMatrix &m)
{
d.write().transform(m);
}
inline void VPath::arcTo(const VRectF &rect, float startAngle,
float sweepLength, bool forceMoveTo)
{
d.write().arcTo(rect, startAngle, sweepLength, forceMoveTo);
}
inline void VPath::addRect(const VRectF &rect, VPath::Direction dir)
{
d.write().addRect(rect, dir);
}
inline void VPath::addRoundRect(const VRectF &rect, float rx, float ry,
VPath::Direction dir)
{
d.write().addRoundRect(rect, rx, ry, dir);
}
inline void VPath::addRoundRect(const VRectF &rect, float roundness,
VPath::Direction dir)
{
d.write().addRoundRect(rect, roundness, dir);
}
inline void VPath::addCircle(float cx, float cy, float radius,
VPath::Direction dir)
{
d.write().addCircle(cx, cy, radius, dir);
}
inline void VPath::addOval(const VRectF &rect, VPath::Direction dir)
{
d.write().addOval(rect, dir);
}
inline void VPath::addPolystar(float points, float innerRadius,
float outerRadius, float innerRoundness,
float outerRoundness, float startAngle, float cx,
float cy, VPath::Direction dir)
{
d.write().addPolystar(points, innerRadius, outerRadius, innerRoundness,
outerRoundness, startAngle, cx, cy, dir);
}
inline void VPath::addPolygon(float points, float radius, float roundness,
float startAngle, float cx, float cy,
VPath::Direction dir)
{
d.write().addPolygon(points, radius, roundness, startAngle, cx, cy, dir);
}
inline void VPath::addPath(const VPath &path)
{
if (path.empty()) return;
if (null()) {
*this = path;
} else {
d.write().addPath(path.d.read());
}
}
inline void VPath::addPath(const VPath &path, const VMatrix &m)
{
if (path.empty()) return;
d.write().addPath(path.d.read(), &m);
}
inline const std::vector<VPath::Element> &VPath::elements() const
{
return d->elements();
}
inline const std::vector<VPointF> &VPath::points() const
{
return d->points();
}
inline void VPath::clone(const VPath &o)
{
d.write().clone(o.d.read());
}
V_END_NAMESPACE
#endif // VPATH_H