[DEV] correct the with of the path and the good closing of a path
This commit is contained in:
parent
6925a59c64
commit
eca4520384
@ -112,7 +112,10 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(),
|
tmpStroke.generate(_myRenderer.getSize(),
|
||||||
_myRenderer.getNumberSubScanLine(),
|
_myRenderer.getNumberSubScanLine(),
|
||||||
|
@ -117,7 +117,10 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(),
|
tmpStroke.generate(_myRenderer.getSize(),
|
||||||
_myRenderer.getNumberSubScanLine(),
|
_myRenderer.getNumberSubScanLine(),
|
||||||
|
@ -85,7 +85,10 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(),
|
tmpStroke.generate(_myRenderer.getSize(),
|
||||||
_myRenderer.getNumberSubScanLine(),
|
_myRenderer.getNumberSubScanLine(),
|
||||||
|
@ -279,7 +279,10 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentStroke);
|
tmpStroke.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentStroke);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,10 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(),
|
tmpStroke.generate(_myRenderer.getSize(),
|
||||||
_myRenderer.getNumberSubScanLine(),
|
_myRenderer.getNumberSubScanLine(),
|
||||||
|
@ -95,7 +95,10 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(),
|
tmpStroke.generate(_myRenderer.getSize(),
|
||||||
_myRenderer.getNumberSubScanLine(),
|
_myRenderer.getNumberSubScanLine(),
|
||||||
|
@ -112,7 +112,10 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
|
|||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if ( m_paint.strokeWidth > 0
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
&& m_paint.stroke.a() != 0x00) {
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints, m_paint.strokeWidth);
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
|
m_paint.strokeWidth,
|
||||||
|
m_paint.lineCap,
|
||||||
|
m_paint.lineJoin);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpStroke.generate(_myRenderer.getSize(),
|
tmpStroke.generate(_myRenderer.getSize(),
|
||||||
_myRenderer.getNumberSubScanLine(),
|
_myRenderer.getNumberSubScanLine(),
|
||||||
|
@ -28,6 +28,10 @@ namespace esvg {
|
|||||||
vec2 m_pos; //!< position of the point
|
vec2 m_pos; //!< position of the point
|
||||||
enum esvg::render::Point::type m_type;
|
enum esvg::render::Point::type m_type;
|
||||||
vec2 m_miterAxe;
|
vec2 m_miterAxe;
|
||||||
|
vec2 m_orthoAxePrevious;
|
||||||
|
vec2 m_orthoAxeNext;
|
||||||
|
vec2 m_posPrevious;
|
||||||
|
vec2 m_posNext;
|
||||||
vec2 m_delta;
|
vec2 m_delta;
|
||||||
float m_len;
|
float m_len;
|
||||||
Point(const vec2& _pos, enum esvg::render::Point::type _type = esvg::render::Point::type_join) :
|
Point(const vec2& _pos, enum esvg::render::Point::type _type = esvg::render::Point::type_join) :
|
||||||
|
@ -43,12 +43,32 @@ void esvg::render::SegmentList::createSegmentList(const esvg::render::PointList&
|
|||||||
std::sort(m_data.begin(), m_data.end(), sortSegmentFunction);
|
std::sort(m_data.begin(), m_data.end(), sortSegmentFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& _listPoint, float _width) {
|
static vec2 getIntersect(const vec2& _point1,
|
||||||
|
const vec2& _vect1,
|
||||||
|
const vec2& _point2,
|
||||||
|
const vec2& _vect2) {
|
||||||
|
float diviseur = _vect1.x() * _vect2.y() - _vect1.y() * _vect2.x();
|
||||||
|
if(diviseur != 0.0f) {
|
||||||
|
float mmm = ( _vect1.x() * _point1.y()
|
||||||
|
- _vect1.x() * _point2.y()
|
||||||
|
- _vect1.y() * _point1.x()
|
||||||
|
+ _vect1.y() * _point2.x()
|
||||||
|
) / diviseur;
|
||||||
|
return vec2(_point2 + _vect2 * mmm);
|
||||||
|
}
|
||||||
|
SVG_ERROR("Get divider / 0.0f");
|
||||||
|
return _point2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& _listPoint,
|
||||||
|
float _width,
|
||||||
|
enum esvg::cap _cap,
|
||||||
|
enum esvg::join _join) {
|
||||||
for (auto &itListPoint : _listPoint.m_data) {
|
for (auto &itListPoint : _listPoint.m_data) {
|
||||||
// generate for every point all the orthogonal elements
|
// generate for every point all the orthogonal elements
|
||||||
//
|
//
|
||||||
// normal edge * end path
|
// normal edge * end path
|
||||||
// * | * * * * * * * * * * * * * *
|
// (mitter) * | * * * * * * * * * * * * * *
|
||||||
// * |<--*----this | *
|
// * |<--*----this | *
|
||||||
// * | * this -->| *
|
// * | * this -->| *
|
||||||
// * * * | *
|
// * * * | *
|
||||||
@ -93,19 +113,33 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
vecC.safeNormalize();
|
vecC.safeNormalize();
|
||||||
itListPoint[idCurrent].m_miterAxe = vecC;
|
itListPoint[idCurrent].m_miterAxe = vecC;
|
||||||
}
|
}
|
||||||
|
itListPoint[idCurrent].m_posPrevious = itListPoint[idPevious].m_pos;
|
||||||
|
itListPoint[idCurrent].m_posNext = itListPoint[idNext].m_pos;
|
||||||
|
vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
||||||
|
vecB.safeNormalize();
|
||||||
|
itListPoint[idCurrent].m_orthoAxeNext = vec2(vecB.y(), -vecB.x());
|
||||||
|
vecB = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
|
||||||
|
vecB.safeNormalize();
|
||||||
|
itListPoint[idCurrent].m_orthoAxePrevious = vec2(vecB.y(), -vecB.x());
|
||||||
//SVG_DEBUG("JOIN : miterAxe " << itListPoint[idCurrent].m_miterAxe);
|
//SVG_DEBUG("JOIN : miterAxe " << itListPoint[idCurrent].m_miterAxe);
|
||||||
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_start) {
|
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_start) {
|
||||||
|
itListPoint[idCurrent].m_posNext = itListPoint[idNext].m_pos;
|
||||||
vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
||||||
vecB.safeNormalize();
|
vecB.safeNormalize();
|
||||||
itListPoint[idCurrent].m_miterAxe = vec2(vecB.y(), -vecB.x());
|
itListPoint[idCurrent].m_miterAxe = vec2(vecB.y(), -vecB.x());
|
||||||
|
itListPoint[idCurrent].m_orthoAxePrevious = itListPoint[idCurrent].m_miterAxe;
|
||||||
|
itListPoint[idCurrent].m_orthoAxeNext = itListPoint[idCurrent].m_miterAxe;
|
||||||
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_stop) {
|
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_stop) {
|
||||||
if (idPevious < 0 ) {
|
if (idPevious < 0 ) {
|
||||||
SVG_ERROR("an error occure a previous ID is < 0.... ");
|
SVG_ERROR("an error occure a previous ID is < 0.... ");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
itListPoint[idCurrent].m_posPrevious = itListPoint[idPevious].m_pos;
|
||||||
vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
|
vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
|
||||||
vecA.safeNormalize();
|
vecA.safeNormalize();
|
||||||
itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), -vecA.x());
|
itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), -vecA.x());
|
||||||
|
itListPoint[idCurrent].m_orthoAxePrevious = itListPoint[idCurrent].m_miterAxe;
|
||||||
|
itListPoint[idCurrent].m_orthoAxeNext = itListPoint[idCurrent].m_miterAxe;
|
||||||
} else {
|
} else {
|
||||||
SVG_TODO("lklklklklkl");
|
SVG_TODO("lklklklklkl");
|
||||||
}
|
}
|
||||||
@ -119,10 +153,14 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
// cyclic path...
|
// cyclic path...
|
||||||
if ( itListPoint.back().m_type == esvg::render::Point::type_join
|
if ( itListPoint.back().m_type == esvg::render::Point::type_join
|
||||||
|| itListPoint.back().m_type == esvg::render::Point::type_interpolation) {
|
|| itListPoint.back().m_type == esvg::render::Point::type_interpolation) {
|
||||||
|
// Calculate the perpendiculary axis ...
|
||||||
leftPoint = itListPoint.back().m_pos
|
leftPoint = itListPoint.back().m_pos
|
||||||
+ itListPoint.back().m_miterAxe*_width*0.5f;
|
+ itListPoint.back().m_orthoAxePrevious*_width*0.5f;
|
||||||
rightPoint = itListPoint.back().m_pos
|
rightPoint = itListPoint.back().m_pos
|
||||||
- itListPoint.back().m_miterAxe*_width*0.5f;
|
- itListPoint.back().m_orthoAxePrevious*_width*0.5f;
|
||||||
|
// project on the miter Axis ...
|
||||||
|
leftPoint = getIntersect(leftPoint, itListPoint.back().m_pos-itListPoint.back().m_posPrevious, itListPoint.back().m_pos, itListPoint.back().m_miterAxe);
|
||||||
|
rightPoint = getIntersect(rightPoint, itListPoint.back().m_pos-itListPoint.back().m_posPrevious, itListPoint.back().m_pos, itListPoint.back().m_miterAxe);
|
||||||
} else {
|
} else {
|
||||||
SVG_ERROR("Start list point with a join, but last lement is not a join");
|
SVG_ERROR("Start list point with a join, but last lement is not a join");
|
||||||
}
|
}
|
||||||
@ -143,7 +181,6 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
addSegment(leftPoint, rightPoint);
|
addSegment(leftPoint, rightPoint);
|
||||||
}
|
}
|
||||||
haveStartLine = true;
|
haveStartLine = true;
|
||||||
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
|
|
||||||
leftPoint = it.m_pos
|
leftPoint = it.m_pos
|
||||||
+ it.m_miterAxe*_width*0.5f;
|
+ it.m_miterAxe*_width*0.5f;
|
||||||
rightPoint = it.m_pos
|
rightPoint = it.m_pos
|
||||||
@ -160,7 +197,6 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
haveStartLine = false;
|
haveStartLine = false;
|
||||||
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
|
|
||||||
vec2 left = it.m_pos
|
vec2 left = it.m_pos
|
||||||
+ it.m_miterAxe*_width*0.5f;
|
+ it.m_miterAxe*_width*0.5f;
|
||||||
vec2 right = it.m_pos
|
vec2 right = it.m_pos
|
||||||
@ -173,7 +209,11 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
leftPoint = left;
|
leftPoint = left;
|
||||||
rightPoint = right;
|
rightPoint = right;
|
||||||
// end line ...
|
// end line ...
|
||||||
addSegment(rightPoint, leftPoint);
|
if (rightPoint.y() <= leftPoint.y()) {
|
||||||
|
addSegment(leftPoint, rightPoint);
|
||||||
|
} else {
|
||||||
|
addSegment(rightPoint, leftPoint);
|
||||||
|
}
|
||||||
SVG_VERBOSE(" segment :" << rightPoint << " -> " << leftPoint);
|
SVG_VERBOSE(" segment :" << rightPoint << " -> " << leftPoint);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -181,10 +221,15 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
{
|
{
|
||||||
SVG_VERBOSE("Find interpolation " << it.m_pos);
|
SVG_VERBOSE("Find interpolation " << it.m_pos);
|
||||||
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
|
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
|
||||||
|
#if 1
|
||||||
|
vec2 left = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
|
||||||
|
vec2 right = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
|
||||||
|
#else
|
||||||
vec2 left = it.m_pos
|
vec2 left = it.m_pos
|
||||||
+ it.m_miterAxe*_width*0.5f;
|
+ it.m_miterAxe*_width*0.5f;
|
||||||
vec2 right = it.m_pos
|
vec2 right = it.m_pos
|
||||||
- it.m_miterAxe*_width*0.5f;
|
- it.m_miterAxe*_width*0.5f;
|
||||||
|
#endif
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint, left);
|
||||||
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
|
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
|
||||||
@ -198,10 +243,15 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
{
|
{
|
||||||
SVG_VERBOSE("Find Join " << it.m_pos);
|
SVG_VERBOSE("Find Join " << it.m_pos);
|
||||||
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
|
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
|
||||||
|
#if 1
|
||||||
|
vec2 left = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
|
||||||
|
vec2 right = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
|
||||||
|
#else
|
||||||
vec2 left = it.m_pos
|
vec2 left = it.m_pos
|
||||||
+ it.m_miterAxe*_width*0.5f;
|
+ it.m_miterAxe*_width*0.5f;
|
||||||
vec2 right = it.m_pos
|
vec2 right = it.m_pos
|
||||||
- it.m_miterAxe*_width*0.5f;
|
- it.m_miterAxe*_width*0.5f;
|
||||||
|
#endif
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint, left);
|
||||||
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
|
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <etk/types.h>
|
#include <etk/types.h>
|
||||||
#include <etk/math/Vector2D.h>
|
#include <etk/math/Vector2D.h>
|
||||||
|
#include <esvg/cap.h>
|
||||||
|
#include <esvg/join.h>
|
||||||
#include <esvg/render/Segment.h>
|
#include <esvg/render/Segment.h>
|
||||||
#include <esvg/render/PointList.h>
|
#include <esvg/render/PointList.h>
|
||||||
|
|
||||||
@ -23,7 +25,10 @@ namespace esvg {
|
|||||||
SegmentList();
|
SegmentList();
|
||||||
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1);
|
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1);
|
||||||
void createSegmentList(const esvg::render::PointList& _listPoint);
|
void createSegmentList(const esvg::render::PointList& _listPoint);
|
||||||
void createSegmentListStroke(esvg::render::PointList& _listPoint, float _width);
|
void createSegmentListStroke(esvg::render::PointList& _listPoint,
|
||||||
|
float _width,
|
||||||
|
enum esvg::cap _cap,
|
||||||
|
enum esvg::join _join);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <etk/types.h>
|
#include <etk/types.h>
|
||||||
#include <etk/math/Vector2D.h>
|
#include <etk/math/Vector2D.h>
|
||||||
|
#include <esvg/Base.h>
|
||||||
#include <esvg/render/Scanline.h>
|
#include <esvg/render/Scanline.h>
|
||||||
#include <esvg/render/SegmentList.h>
|
#include <esvg/render/SegmentList.h>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user