mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 21:41:45 +00:00
lottie/vector: refactor vpath class to use vcow_ptr
Change-Id: Ib16da52a8a97bbee87766ee362e1d6e5678ac305
This commit is contained in:
parent
8c20000b08
commit
84c0411929
@ -7,56 +7,34 @@
|
||||
|
||||
V_BEGIN_NAMESPACE
|
||||
|
||||
struct VPathData
|
||||
{
|
||||
VPathData():ref(-1),
|
||||
m_points(),
|
||||
m_elements(),
|
||||
m_segments(0),
|
||||
mStartPoint(),
|
||||
mNewSegment(true){}
|
||||
VPath::VPathData::VPathData():m_points(),
|
||||
m_elements(),
|
||||
m_segments(0),
|
||||
mStartPoint(),
|
||||
mNewSegment(true){}
|
||||
|
||||
void copy(VPathData *o);
|
||||
void moveTo(const VPointF &pt);
|
||||
void lineTo(const VPointF &pt);
|
||||
void cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e);
|
||||
void close();
|
||||
void reset();
|
||||
void checkNewSegment();
|
||||
int segments() const;
|
||||
void transform(const VMatrix &m);
|
||||
RefCount ref;
|
||||
std::vector<VPointF> m_points;
|
||||
std::vector<VPath::Element> m_elements;
|
||||
int m_segments;
|
||||
VPointF mStartPoint;
|
||||
bool mNewSegment;
|
||||
};
|
||||
VPath::VPathData::VPathData(const VPathData &o):m_points(o.m_points),
|
||||
m_elements(o.m_elements),
|
||||
m_segments(o.m_segments),
|
||||
mStartPoint(o.mStartPoint),
|
||||
mNewSegment(o.mNewSegment){}
|
||||
|
||||
|
||||
void VPathData::transform(const VMatrix &m)
|
||||
void VPath::VPathData::transform(const VMatrix &m)
|
||||
{
|
||||
for(auto &i : m_points) {
|
||||
i = m.map(i);
|
||||
}
|
||||
}
|
||||
|
||||
void VPathData::checkNewSegment()
|
||||
void VPath::VPathData::checkNewSegment()
|
||||
{
|
||||
if (mNewSegment) {
|
||||
moveTo(VPointF(0,0));
|
||||
mNewSegment = false;
|
||||
}
|
||||
}
|
||||
void VPathData::copy(VPathData *o)
|
||||
{
|
||||
m_points = o->m_points;
|
||||
m_elements = o->m_elements;
|
||||
m_segments = o->m_segments;
|
||||
mStartPoint = o->mStartPoint;
|
||||
}
|
||||
|
||||
void VPathData::moveTo(const VPointF &p)
|
||||
void VPath::VPathData::moveTo(const VPointF &p)
|
||||
{
|
||||
mStartPoint = p;
|
||||
mNewSegment = false;
|
||||
@ -64,13 +42,13 @@ void VPathData::moveTo(const VPointF &p)
|
||||
m_points.push_back(p);
|
||||
m_segments++;
|
||||
}
|
||||
void VPathData::lineTo(const VPointF &p)
|
||||
void VPath::VPathData::lineTo(const VPointF &p)
|
||||
{
|
||||
checkNewSegment();
|
||||
m_elements.push_back(VPath::Element::LineTo);
|
||||
m_points.push_back(p);
|
||||
}
|
||||
void VPathData::cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e)
|
||||
void VPath::VPathData::cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e)
|
||||
{
|
||||
checkNewSegment();
|
||||
m_elements.push_back(VPath::Element::CubicTo);
|
||||
@ -79,8 +57,10 @@ void VPathData::cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e)
|
||||
m_points.push_back(e);
|
||||
}
|
||||
|
||||
void VPathData::close()
|
||||
void VPath::VPathData::close()
|
||||
{
|
||||
if (isEmpty()) return;
|
||||
|
||||
const VPointF &lastPt = m_points.back();
|
||||
if (!fuzzyCompare(mStartPoint, lastPt)) {
|
||||
lineTo(mStartPoint);
|
||||
@ -89,144 +69,149 @@ void VPathData::close()
|
||||
mNewSegment = true;
|
||||
}
|
||||
|
||||
void VPathData::reset()
|
||||
void VPath::VPathData::reset()
|
||||
{
|
||||
if (isEmpty()) return;
|
||||
|
||||
m_elements.clear();
|
||||
m_points.clear();
|
||||
m_segments = 0;
|
||||
}
|
||||
|
||||
int VPathData::segments() const
|
||||
int VPath::VPathData::segments() const
|
||||
{
|
||||
return m_segments;
|
||||
return m_segments + 1;
|
||||
}
|
||||
|
||||
|
||||
static const struct VPathData shared_empty;
|
||||
|
||||
inline void VPath::cleanUp(VPathData *d)
|
||||
void VPath::VPathData::reserve(int num_elm)
|
||||
{
|
||||
delete d;
|
||||
m_elements.reserve(num_elm);
|
||||
m_points.reserve(2 * num_elm);
|
||||
}
|
||||
|
||||
void VPath::detach()
|
||||
static VPointF curvesForArc(const VRectF &, float, float, VPointF *, int *);
|
||||
static constexpr float PATH_KAPPA = 0.5522847498;
|
||||
|
||||
void VPath::VPathData::arcTo(const VRectF &rect, float startAngle, float sweepLength, bool forceMoveTo)
|
||||
{
|
||||
if (d->ref.isShared())
|
||||
*this = copy();
|
||||
int point_count = 0;
|
||||
VPointF pts[15];
|
||||
VPointF curve_start = curvesForArc(rect, startAngle, sweepLength, pts, &point_count);
|
||||
|
||||
if (isEmpty() || forceMoveTo) {
|
||||
moveTo(curve_start);
|
||||
} else {
|
||||
lineTo(curve_start);
|
||||
}
|
||||
for (int i=0; i<point_count; i+=3) {
|
||||
cubicTo(pts[i], pts[i+1], pts[i+2]);
|
||||
}
|
||||
}
|
||||
|
||||
VPath VPath::copy() const
|
||||
void VPath::VPathData::addCircle(float cx, float cy, float radius, VPath::Direction dir)
|
||||
{
|
||||
VPath other;
|
||||
|
||||
other.d = new VPathData;
|
||||
other.d->m_points = d->m_points;
|
||||
other.d->m_elements = d->m_elements;
|
||||
other.d->m_segments = d->m_segments;
|
||||
other.d->ref.setOwned();
|
||||
return other;
|
||||
addOval(VRectF(cx-radius, cy-radius, 2*radius, 2*radius) , dir);
|
||||
}
|
||||
|
||||
VPath::~VPath()
|
||||
void VPath::VPathData::addOval(const VRectF &rect, VPath::Direction dir)
|
||||
{
|
||||
if (!d->ref.deref())
|
||||
cleanUp(d);
|
||||
if (rect.isNull()) return;
|
||||
|
||||
float x = rect.x();
|
||||
float y = rect.y();
|
||||
|
||||
float w = rect.width();
|
||||
float w2 = rect.width() / 2;
|
||||
float w2k = w2 * PATH_KAPPA;
|
||||
|
||||
float h = rect.height();
|
||||
float h2 = rect.height() / 2;
|
||||
float h2k = h2 * PATH_KAPPA;
|
||||
|
||||
|
||||
if (dir == VPath::Direction::CW) {
|
||||
// moveto 12 o'clock.
|
||||
moveTo(VPointF(x+w2, y));
|
||||
// 12 -> 3 o'clock
|
||||
cubicTo(VPointF(x + w2 + w2k, y), VPointF(x + w, y + h2 - h2k), VPointF(x + w, y + h2));
|
||||
// 3 -> 6 o'clock
|
||||
cubicTo(VPointF(x + w, y + h2 + h2k), VPointF(x + w2 + w2k, y + h), VPointF(x + w2, y + h));
|
||||
// 6 -> 9 o'clock
|
||||
cubicTo(VPointF(x + w2 - w2k, y + h), VPointF(x, y + h2 + h2k), VPointF(x , y + h2));
|
||||
// 9 -> 12 o'clock
|
||||
cubicTo(VPointF(x, y + h2 - h2k), VPointF(x + w2 - w2k, y), VPointF(x + w2, y));
|
||||
} else {
|
||||
// moveto 12 o'clock.
|
||||
moveTo(VPointF(x+w2, y));
|
||||
// 12 -> 9 o'clock
|
||||
cubicTo(VPointF(x + w2 - w2k, y), VPointF(x, y + h2 - h2k), VPointF(x , y + h2));
|
||||
// 9 -> 6 o'clock
|
||||
cubicTo(VPointF(x, y + h2 + h2k), VPointF(x + w2 - w2k, y + h), VPointF(x + w2, y + h));
|
||||
// 6 -> 3 o'clock
|
||||
cubicTo(VPointF(x + w2 + w2k, y + h), VPointF(x + w, y + h2 + h2k), VPointF(x + w, y + h2));
|
||||
// 3 -> 12 o'clock
|
||||
cubicTo(VPointF(x + w, y + h2 - h2k), VPointF(x + w2 + w2k, y), VPointF(x+w2, y));
|
||||
}
|
||||
}
|
||||
|
||||
VPath::VPath()
|
||||
: d(const_cast<VPathData*>(&shared_empty))
|
||||
void VPath::VPathData::addRect(const VRectF &rect, VPath::Direction dir)
|
||||
{
|
||||
if (rect.isNull()) return;
|
||||
|
||||
float x = rect.x();
|
||||
float y = rect.y();
|
||||
float w = rect.width();
|
||||
float h = rect.height();
|
||||
|
||||
if (dir == VPath::Direction::CW) {
|
||||
moveTo(VPointF(x + w, y));
|
||||
lineTo(VPointF(x + w, y + h));
|
||||
lineTo(VPointF(x , y + h));
|
||||
lineTo(VPointF(x , y));
|
||||
close();
|
||||
} else {
|
||||
moveTo(VPointF(x + w, y));
|
||||
lineTo(VPointF(x , y));
|
||||
lineTo(VPointF(x , y + h));
|
||||
lineTo(VPointF(x + w, y + h));
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
VPath::VPath(const VPath &other)
|
||||
void VPath::VPathData::addRoundRect(const VRectF &rect, float rx, float ry, VPath::Direction dir)
|
||||
{
|
||||
d = other.d;
|
||||
d->ref.ref();
|
||||
}
|
||||
if (vCompare(rx, 0.f) || vCompare(ry, 0.f)) {
|
||||
addRect(rect, dir);
|
||||
return;
|
||||
}
|
||||
|
||||
VPath::VPath(VPath &&other): d(other.d)
|
||||
{
|
||||
other.d = const_cast<VPathData*>(&shared_empty);
|
||||
}
|
||||
float x = rect.x();
|
||||
float y = rect.y();
|
||||
float w = rect.width();
|
||||
float h = rect.height();
|
||||
// clamp the rx and ry radius value.
|
||||
rx = 2*rx;
|
||||
ry = 2*ry;
|
||||
if (rx > w) rx = w;
|
||||
if (ry > h) ry = h;
|
||||
|
||||
VPath &VPath::operator=(const VPath &other)
|
||||
{
|
||||
other.d->ref.ref();
|
||||
if (!d->ref.deref())
|
||||
cleanUp(d);
|
||||
|
||||
d = other.d;
|
||||
return *this;
|
||||
if (dir == VPath::Direction::CW) {
|
||||
moveTo(VPointF(x + w, y + ry/2.f));
|
||||
arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 0 , -90, false);
|
||||
arcTo(VRectF(x, y + h - ry, rx, ry), -90 , -90, false);
|
||||
arcTo(VRectF(x, y, rx, ry), -180 , -90, false);
|
||||
arcTo(VRectF(x + w - rx, y, rx, ry), -270 , -90, false);
|
||||
close();
|
||||
} else {
|
||||
moveTo(VPointF(x + w, y + ry/2.f));
|
||||
arcTo(VRectF(x + w - rx, y , rx, ry), 0 , 90, false);
|
||||
arcTo(VRectF(x, y, rx, ry), 90 , 90, false);
|
||||
arcTo(VRectF(x, y + h - ry, rx, ry), 180 , 90, false);
|
||||
arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 270 , 90, false);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
inline VPath &VPath::operator=(VPath &&other)
|
||||
{
|
||||
if (!d->ref.deref())
|
||||
cleanUp(d);
|
||||
d = other.d;
|
||||
other.d = const_cast<VPathData*>(&shared_empty);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool VPath::isEmpty()const
|
||||
{
|
||||
return d->m_elements.empty();
|
||||
}
|
||||
|
||||
void VPath::close()
|
||||
{
|
||||
if (isEmpty()) return;
|
||||
detach();
|
||||
d->close();
|
||||
}
|
||||
|
||||
void VPath::reset()
|
||||
{
|
||||
if (isEmpty()) return;
|
||||
detach();
|
||||
d->reset();
|
||||
}
|
||||
|
||||
void VPath::moveTo(const VPointF &p)
|
||||
{
|
||||
detach();
|
||||
d->moveTo(p);
|
||||
}
|
||||
|
||||
void VPath::lineTo(const VPointF &p)
|
||||
{
|
||||
detach();
|
||||
d->lineTo(p);
|
||||
}
|
||||
|
||||
void VPath::cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e)
|
||||
{
|
||||
detach();
|
||||
d->cubicTo(c1, c2, e);
|
||||
}
|
||||
|
||||
void VPath::reserve(int num_elm)
|
||||
{
|
||||
detach();
|
||||
d->m_elements.reserve(num_elm);
|
||||
d->m_points.reserve(num_elm);
|
||||
}
|
||||
|
||||
const std::vector<VPath::Element> &VPath::elements() const
|
||||
{
|
||||
return d->m_elements;
|
||||
}
|
||||
const std::vector<VPointF> &VPath::points() const
|
||||
{
|
||||
return d->m_points;
|
||||
}
|
||||
int VPath::segments() const
|
||||
{
|
||||
return d->m_segments + 1;
|
||||
}
|
||||
|
||||
#define PATH_KAPPA 0.5522847498
|
||||
|
||||
static float tForArcAngle(float angle);
|
||||
void findEllipseCoords(const VRectF &r, float angle, float length,
|
||||
VPointF* startPoint, VPointF *endPoint)
|
||||
@ -454,132 +439,6 @@ curvesForArc(const VRectF &rect, float startAngle, float sweepLength,
|
||||
return startPoint;
|
||||
}
|
||||
|
||||
void VPath::arcTo(const VRectF &rect, float startAngle, float sweepLength, bool forceMoveTo)
|
||||
{
|
||||
detach();
|
||||
|
||||
int point_count = 0;
|
||||
VPointF pts[15];
|
||||
VPointF curve_start = curvesForArc(rect, startAngle, sweepLength, pts, &point_count);
|
||||
|
||||
if (isEmpty() || forceMoveTo) {
|
||||
d->moveTo(curve_start);
|
||||
} else {
|
||||
d->lineTo(curve_start);
|
||||
}
|
||||
for (int i=0; i<point_count; i+=3) {
|
||||
d->cubicTo(pts[i], pts[i+1], pts[i+2]);
|
||||
}
|
||||
}
|
||||
|
||||
void VPath::addCircle(float cx, float cy, float radius, VPath::Direction dir)
|
||||
{
|
||||
addOval(VRectF(cx-radius, cy-radius, 2*radius, 2*radius) , dir);
|
||||
}
|
||||
|
||||
void VPath::addOval(const VRectF &rect, VPath::Direction dir)
|
||||
{
|
||||
if (rect.isNull()) return;
|
||||
|
||||
detach();
|
||||
|
||||
float x = rect.x();
|
||||
float y = rect.y();
|
||||
|
||||
float w = rect.width();
|
||||
float w2 = rect.width() / 2;
|
||||
float w2k = w2 * PATH_KAPPA;
|
||||
|
||||
float h = rect.height();
|
||||
float h2 = rect.height() / 2;
|
||||
float h2k = h2 * PATH_KAPPA;
|
||||
|
||||
|
||||
if (dir == VPath::Direction::CW) {
|
||||
// moveto 12 o'clock.
|
||||
d->moveTo(VPointF(x+w2, y));
|
||||
// 12 -> 3 o'clock
|
||||
d->cubicTo(VPointF(x + w2 + w2k, y), VPointF(x + w, y + h2 - h2k), VPointF(x + w, y + h2));
|
||||
// 3 -> 6 o'clock
|
||||
d->cubicTo(VPointF(x + w, y + h2 + h2k), VPointF(x + w2 + w2k, y + h), VPointF(x + w2, y + h));
|
||||
// 6 -> 9 o'clock
|
||||
d->cubicTo(VPointF(x + w2 - w2k, y + h), VPointF(x, y + h2 + h2k), VPointF(x , y + h2));
|
||||
// 9 -> 12 o'clock
|
||||
d->cubicTo(VPointF(x, y + h2 - h2k), VPointF(x + w2 - w2k, y), VPointF(x + w2, y));
|
||||
} else {
|
||||
// moveto 12 o'clock.
|
||||
d->moveTo(VPointF(x+w2, y));
|
||||
// 12 -> 9 o'clock
|
||||
d->cubicTo(VPointF(x + w2 - w2k, y), VPointF(x, y + h2 - h2k), VPointF(x , y + h2));
|
||||
// 9 -> 6 o'clock
|
||||
d->cubicTo(VPointF(x, y + h2 + h2k), VPointF(x + w2 - w2k, y + h), VPointF(x + w2, y + h));
|
||||
// 6 -> 3 o'clock
|
||||
d->cubicTo(VPointF(x + w2 + w2k, y + h), VPointF(x + w, y + h2 + h2k), VPointF(x + w, y + h2));
|
||||
// 3 -> 12 o'clock
|
||||
d->cubicTo(VPointF(x + w, y + h2 - h2k), VPointF(x + w2 + w2k, y), VPointF(x+w2, y));
|
||||
}
|
||||
}
|
||||
|
||||
void VPath::addRect(const VRectF &rect, VPath::Direction dir)
|
||||
{
|
||||
if (rect.isNull()) return;
|
||||
|
||||
detach();
|
||||
|
||||
float x = rect.x();
|
||||
float y = rect.y();
|
||||
float w = rect.width();
|
||||
float h = rect.height();
|
||||
|
||||
if (dir == VPath::Direction::CW) {
|
||||
moveTo(VPointF(x + w, y));
|
||||
lineTo(VPointF(x + w, y + h));
|
||||
lineTo(VPointF(x , y + h));
|
||||
lineTo(VPointF(x , y));
|
||||
close();
|
||||
} else {
|
||||
moveTo(VPointF(x + w, y));
|
||||
lineTo(VPointF(x , y));
|
||||
lineTo(VPointF(x , y + h));
|
||||
lineTo(VPointF(x + w, y + h));
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void VPath::addRoundRect(const VRectF &rect, float rx, float ry, VPath::Direction dir)
|
||||
{
|
||||
if (vCompare(rx, 0.f) || vCompare(ry, 0.f)) {
|
||||
addRect(rect, dir);
|
||||
return;
|
||||
}
|
||||
|
||||
float x = rect.x();
|
||||
float y = rect.y();
|
||||
float w = rect.width();
|
||||
float h = rect.height();
|
||||
// clamp the rx and ry radius value.
|
||||
rx = 2*rx;
|
||||
ry = 2*ry;
|
||||
if (rx > w) rx = w;
|
||||
if (ry > h) ry = h;
|
||||
|
||||
if (dir == VPath::Direction::CW) {
|
||||
moveTo(VPointF(x + w, y + ry/2.f));
|
||||
arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 0 , -90, false);
|
||||
arcTo(VRectF(x, y + h - ry, rx, ry), -90 , -90, false);
|
||||
arcTo(VRectF(x, y, rx, ry), -180 , -90, false);
|
||||
arcTo(VRectF(x + w - rx, y, rx, ry), -270 , -90, false);
|
||||
close();
|
||||
} else {
|
||||
moveTo(VPointF(x + w, y + ry/2.f));
|
||||
arcTo(VRectF(x + w - rx, y , rx, ry), 0 , 90, false);
|
||||
arcTo(VRectF(x, y, rx, ry), 90 , 90, false);
|
||||
arcTo(VRectF(x, y + h - ry, rx, ry), 180 , 90, false);
|
||||
arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 270 , 90, false);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void VPath::addPolystarStar(float startAngle, float cx, float cy, float points,
|
||||
float innerRadius, float outerRadius,
|
||||
float innerRoundness, float outerRoundness,
|
||||
@ -617,7 +476,9 @@ void VPath::addPolystarStar(float startAngle, float cx, float cy, float points,
|
||||
currentAngle += halfAnglePerPoint * angleDir;
|
||||
}
|
||||
|
||||
moveTo(VPointF(x + cx, y + cy));
|
||||
VPathData &ref = d.write();
|
||||
|
||||
ref.moveTo(VPointF(x + cx, y + cy));
|
||||
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
float radius = longSegment ? outerRadius : innerRadius;
|
||||
@ -634,7 +495,7 @@ void VPath::addPolystarStar(float startAngle, float cx, float cy, float points,
|
||||
y = (float) (radius * sin(currentAngle));
|
||||
|
||||
if (innerRoundness == 0 && outerRoundness == 0) {
|
||||
lineTo(VPointF(x + cx, y + cy));
|
||||
ref.lineTo(VPointF(x + cx, y + cy));
|
||||
} else {
|
||||
float cp1Theta = (float) (atan2(previousY, previousX) - M_PI / 2.0 * angleDir);
|
||||
float cp1Dx = (float) cos(cp1Theta);
|
||||
@ -661,9 +522,9 @@ void VPath::addPolystarStar(float startAngle, float cx, float cy, float points,
|
||||
cp2y *= partialPointAmount;
|
||||
}
|
||||
|
||||
cubicTo(VPointF(previousX - cp1x + cx, previousY - cp1y + cy),
|
||||
VPointF(x + cp2x + cx, y + cp2y + cy),
|
||||
VPointF(x + cx, y + cy));
|
||||
ref.cubicTo(VPointF(previousX - cp1x + cx, previousY - cp1y + cy),
|
||||
VPointF(x + cp2x + cx, y + cp2y + cy),
|
||||
VPointF(x + cx, y + cy));
|
||||
}
|
||||
|
||||
currentAngle += dTheta * angleDir;
|
||||
@ -729,11 +590,4 @@ void VPath::addPolystarPolygon(float startAngle, float cx, float cy, float point
|
||||
close();
|
||||
}
|
||||
|
||||
void VPath::transform(const VMatrix &m)
|
||||
{
|
||||
if (isEmpty()) return;
|
||||
detach();
|
||||
d->transform(m);
|
||||
}
|
||||
|
||||
V_END_NAMESPACE
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "vrect.h"
|
||||
#include "vmatrix.h"
|
||||
#include<vector>
|
||||
#include<vcowptr.h>
|
||||
|
||||
V_BEGIN_NAMESPACE
|
||||
|
||||
@ -22,24 +23,18 @@ public:
|
||||
CubicTo,
|
||||
Close
|
||||
};
|
||||
~VPath();
|
||||
VPath();
|
||||
VPath(const VPath &path);
|
||||
VPath(VPath &&other);
|
||||
VPath &operator=(const VPath &);
|
||||
VPath &operator=(VPath &&other);
|
||||
bool isEmpty()const;
|
||||
void moveTo(const VPointF &p);
|
||||
inline void moveTo(float x, float y);
|
||||
void moveTo(float x, float y);
|
||||
void lineTo(const VPointF &p);
|
||||
inline void lineTo(float x, float y);
|
||||
void lineTo(float x, float y);
|
||||
void cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e);
|
||||
inline void cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey);
|
||||
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(int num_elm);
|
||||
|
||||
int 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);
|
||||
@ -51,19 +46,80 @@ public:
|
||||
void addPolystarPolygon(float startAngle, float cx, float cy, float points,
|
||||
float radius, float roundness,
|
||||
VPath::Direction dir = Direction::CW);
|
||||
|
||||
void transform(const VMatrix &m);
|
||||
const std::vector<VPath::Element> &elements() const;
|
||||
const std::vector<VPointF> &points() const;
|
||||
private:
|
||||
friend class VRaster;
|
||||
int segments() const;
|
||||
VPath copy() const;
|
||||
void detach();
|
||||
void cleanUp(VPathData *x);
|
||||
VPathData *d;
|
||||
struct VPathData {
|
||||
VPathData();
|
||||
VPathData(const VPathData &o);
|
||||
bool isEmpty() const { return m_elements.empty();}
|
||||
void moveTo(const VPointF &pt);
|
||||
void lineTo(const VPointF &pt);
|
||||
void cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e);
|
||||
void close();
|
||||
void reset();
|
||||
void reserve(int num_elm);
|
||||
void checkNewSegment();
|
||||
int segments() const;
|
||||
void transform(const VMatrix &m);
|
||||
void addRoundRect(const VRectF &, float, 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);
|
||||
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;
|
||||
int m_segments;
|
||||
VPointF mStartPoint;
|
||||
bool mNewSegment;
|
||||
};
|
||||
|
||||
vcow_ptr<VPathData> d;
|
||||
};
|
||||
|
||||
inline bool VPath::isEmpty()const
|
||||
{
|
||||
return d->isEmpty();
|
||||
}
|
||||
|
||||
inline void VPath::moveTo(const VPointF &p)
|
||||
{
|
||||
d.write().moveTo(p);
|
||||
}
|
||||
|
||||
inline void VPath::lineTo(const VPointF &p)
|
||||
{
|
||||
d.write().lineTo(p);
|
||||
}
|
||||
|
||||
inline void VPath::close()
|
||||
{
|
||||
d.write().close();
|
||||
}
|
||||
|
||||
inline void VPath::reset()
|
||||
{
|
||||
d.write().reset();
|
||||
}
|
||||
|
||||
inline void VPath::reserve(int num_elm)
|
||||
{
|
||||
d.write().reserve(num_elm);
|
||||
}
|
||||
|
||||
inline int VPath::segments() const
|
||||
{
|
||||
return d->segments();
|
||||
}
|
||||
|
||||
inline void VPath::cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e)
|
||||
{
|
||||
d.write().cubicTo(c1, c2, e);
|
||||
}
|
||||
|
||||
inline void VPath::lineTo(float x, float y)
|
||||
{
|
||||
lineTo(VPointF(x,y));
|
||||
@ -76,7 +132,47 @@ inline void VPath::moveTo(float x, float y)
|
||||
|
||||
inline void VPath::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey)
|
||||
{
|
||||
cubicTo(VPointF(c1x, c1y), VPointF(c2x, c2y), VPointF(ex, ey));
|
||||
cubicTo(VPointF(c1x, c1y), VPointF(c2x, c2y), VPointF(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::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 const std::vector<VPath::Element> &VPath::elements() const
|
||||
{
|
||||
return d->elements();
|
||||
}
|
||||
|
||||
inline const std::vector<VPointF> &VPath::points() const
|
||||
{
|
||||
return d->points();
|
||||
}
|
||||
|
||||
V_END_NAMESPACE
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user