[DEV] Create correct join_roind and factorize rounding and add miter-limit

This commit is contained in:
Edouard DUPIN 2015-12-01 21:27:52 +01:00
parent 9b7a8a6d5a
commit ef8d2a889e
13 changed files with 415 additions and 85 deletions

View File

@ -23,6 +23,7 @@ esvg::PaintState::PaintState() :
flagEvenOdd(false),
lineCap(esvg::cap_butt),
lineJoin(esvg::join_miter),
miterLimit(4.0f),
viewPort(255,255),
opacity(1.0) {
@ -36,6 +37,7 @@ void esvg::PaintState::clear() {
flagEvenOdd = false;
lineJoin = esvg::join_miter;
lineCap = esvg::cap_butt;
miterLimit = 4.0f;
opacity = 1.0;
}
@ -168,21 +170,29 @@ float esvg::Base::parseLength(const std::string& _dataInput) {
return n;
} else if (unit[0] == '%') { // xxx %
return n / 100.0 * m_paint.viewPort.x();
} else if (unit[0] == 'e' && unit[1] == 'm') { // xxx em
} else if ( unit[0] == 'e'
&& unit[1] == 'm') { // xxx em
return n * font_size;
} else if (unit[0] == 'e' && unit[1] == 'x') { // xxx ex
} else if ( unit[0] == 'e'
&& unit[1] == 'x') { // xxx ex
return n / 2.0f * font_size;
} else if (unit[0] == 'p' && unit[1] == 'x') { // xxx px
} else if ( unit[0] == 'p'
&& unit[1] == 'x') { // xxx px
return n;
} else if (unit[0] == 'p' && unit[1] == 't') { // xxx pt
} else if ( unit[0] == 'p'
&& unit[1] == 't') { // xxx pt
return n * 1.25f;
} else if (unit[0] == 'p' && unit[1] == 'c') { // xxx pc
} else if ( unit[0] == 'p'
&& unit[1] == 'c') { // xxx pc
return n * 15.0f;
} else if (unit[0] == 'm' && unit[1] == 'm') { // xxx mm
} else if ( unit[0] == 'm'
&& unit[1] == 'm') { // xxx mm
return n * 3.543307f;
} else if (unit[0] == 'c' && unit[1] == 'm') { // xxx cm
} else if ( unit[0] == 'c'
&& unit[1] == 'm') { // xxx cm
return n * 35.43307f;
} else if (unit[0] == 'i' && unit[1] == 'n') { // xxx in
} else if ( unit[0] == 'i'
&& unit[1] == 'n') { // xxx in
return n * 90.0f;
}
return 0.0f;
@ -255,13 +265,13 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
content = _element->getAttribute("fill-opacity");
if (content.size()!=0) {
float opacity = parseLength(content);
opacity = std::avg(0.0f, opacity, 1.0f);
opacity = std::avg(0.0f, opacity, 1.0f);
m_paint.fill.setA(opacity*0xFF);
}
content = _element->getAttribute("stroke-opacity");
if (content.size()!=0) {
float opacity = parseLength(content);
opacity = std::avg(0.0f, opacity, 1.0f);
opacity = std::avg(0.0f, opacity, 1.0f);
m_paint.stroke.setA(opacity*0xFF);
}
content = _element->getAttribute("fill-rule");
@ -300,6 +310,11 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
SVG_ERROR("not know stroke-linejoin value : \"" << content << "\", not in [miter,round,bevel]");
}
}
content = _element->getAttribute("stroke-miterlimit");
if (content.size()!=0) {
float tmp = parseLength(content);
m_paint.miterLimit = std::max(0.0f, tmp);
}
content = _element->getAttribute("style");
if (content.size()!=0) {
std::string outputType;

View File

@ -53,6 +53,7 @@ namespace esvg {
bool flagEvenOdd; //!< Fill rules
enum esvg::cap lineCap;
enum esvg::join lineJoin;
float miterLimit;
vec2 viewPort;
float opacity;
};

View File

@ -115,7 +115,8 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -120,7 +120,8 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -88,7 +88,8 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -282,7 +282,8 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentStroke);
}

View File

@ -101,7 +101,8 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -98,7 +98,8 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -115,7 +115,8 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin);
m_paint.lineJoin,
m_paint.miterLimit);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -24,9 +24,11 @@ esvg::Renderer::Renderer(const ivec2& _size, bool _visualDebug) :
m_interpolationRecurtionMax(10),
m_interpolationThreshold(0.25f),
m_nbSubScanLine(8) {
if (m_visualDebug == true) {
m_factor = 10;
}
#ifdef DEBUG
if (m_visualDebug == true) {
m_factor = 10;
}
#endif
setSize(_size);
}

View File

@ -56,10 +56,54 @@ static vec2 getIntersect(const vec2& _point1,
return _point2;
}
void esvg::render::SegmentList::createSegmentListStroke(const vec2& _point1,
const vec2& _point2,
const vec2& _center,
float _width,
bool _isStart) {
int32_t nbDot = int32_t(_width);
if (nbDot <= 2) {
nbDot = 2;
}
float angleToDraw = acos((_point1 - _center).safeNormalize().dot((_point2 - _center).safeNormalize()));
float baseAngle = angleToDraw/float(nbDot);
float iii;
vec2 axe = (_point1 - _center).safeNormalize();
vec2 ppp1(_point1);
vec2 ppp2(_point2);
for (iii=baseAngle; iii<angleToDraw; iii+=baseAngle) {
mat2 tmpMat;
if (_isStart == true) {
tmpMat = etk::mat2Rotate(-iii);
} else {
tmpMat = etk::mat2Rotate(iii);
}
vec2 axeRotate = tmpMat * axe;
ppp2 = _center
+ axeRotate*_width*0.5f;
if (_isStart == true) {
addSegment(ppp2, ppp1);
SVG_VERBOSE(" segment :" << ppp2 << " -> " << ppp1);
} else {
addSegment(ppp1, ppp2);
SVG_VERBOSE(" segment :" << ppp1 << " -> " << ppp2);
}
ppp1 = ppp2;
}
if (_isStart == true) {
addSegment(_point2, ppp1);
SVG_VERBOSE(" segment :" << _point2 << " -> " << ppp1);
} else {
addSegment(ppp1, _point2);
SVG_VERBOSE(" segment :" << ppp1 << " -> " << _point2);
}
}
void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& _listPoint,
float _width,
enum esvg::cap _cap,
enum esvg::join _join) {
enum esvg::join _join,
float _miterLimit) {
for (auto &itListPoint : _listPoint.m_data) {
// generate for every point all the orthogonal elements
//
@ -136,7 +180,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
itListPoint[idCurrent].m_orthoAxePrevious = itListPoint[idCurrent].m_miterAxe;
itListPoint[idCurrent].m_orthoAxeNext = itListPoint[idCurrent].m_miterAxe;
} else {
SVG_TODO("lklklklklkl");
SVG_TODO("Unsupported type of point ....");
}
}
// create segment list:
@ -207,15 +251,25 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
{
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);
//Draw from previous point:
addSegment(leftPoint, left);
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
addSegment(right, rightPoint);
SVG_VERBOSE(" segment :" << right << " -> " << rightPoint);
leftPoint = left;
rightPoint = right;
// Check the miter limit:
float limitRight = (left - it.m_pos).length() / _width * 2.0f;
float limitLeft = (right - it.m_pos).length() / _width * 2.0f;
SVG_VERBOSE(" miter Limit: " << limitRight << " " << limitLeft << " <= " << _miterLimit);
if ( limitRight <= _miterLimit
&& limitLeft <= _miterLimit) {
//Draw from previous point:
addSegment(leftPoint, left);
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
addSegment(right, rightPoint);
SVG_VERBOSE(" segment :" << right << " -> " << rightPoint);
leftPoint = left;
rightPoint = right;
break;
} else {
// We do a bevel join ...
SVG_VERBOSE(" Find miter Limit ... ==> create BEVEL");
}
}
break;
case esvg::join_round:
case esvg::join_bevel:
{
@ -232,11 +286,16 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
//Draw from previous point:
addSegment(leftPoint, left1);
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left1);
if (_join == esvg::join_bevel) {
if (_join != esvg::join_round) {
// Miter and bevel:
addSegment(left1, left2);
SVG_VERBOSE(" segment :" << left1 << " -> " << left2);
}else {
createSegmentListStroke(left1,
left2,
it.m_pos,
_width,
false);
}
addSegment(right, rightPoint);
SVG_VERBOSE(" segment :" << right << " -> " << rightPoint);
@ -252,11 +311,16 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
addSegment(right1, rightPoint);
SVG_VERBOSE(" segment :" << right1 << " -> " << rightPoint);
if (_join == esvg::join_bevel) {
if (_join != esvg::join_round) {
// Miter and bevel:
addSegment(right2, right1);
SVG_VERBOSE(" segment :" << right2 << " -> " << right1);
} else {
createSegmentListStroke(right1,
right2,
it.m_pos,
_width,
true);
}
leftPoint = left;
rightPoint = right2;
@ -270,8 +334,6 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
}
}
void esvg::render::SegmentList::startStopPoint(vec2& _leftPoint,
vec2& _rightPoint,
const esvg::render::Point& _point,
@ -326,38 +388,15 @@ void esvg::render::SegmentList::startStopPoint(vec2& _leftPoint,
}
float baseAngle = M_PI/float(nbDot);
float iii;
_rightPoint = _point.m_pos
- _point.m_miterAxe*_width*0.5f;
vec2 storeOld(_rightPoint);
for (iii=baseAngle; iii<M_PI; iii+=baseAngle) {
mat2 tmpMat;
if (_isStart == true) {
tmpMat = etk::mat2Rotate(iii);
} else {
tmpMat = etk::mat2Rotate(-iii);
}
vec2 miterRotate = tmpMat * _point.m_miterAxe;
_leftPoint = _point.m_pos
- miterRotate*_width*0.5f;
if (_isStart == false) {
addSegment(_leftPoint, _rightPoint);
SVG_VERBOSE(" segment :" << _leftPoint << " -> " << _rightPoint);
} else {
addSegment(_rightPoint, _leftPoint);
SVG_VERBOSE(" segment :" << _rightPoint << " -> " << _leftPoint);
}
_rightPoint = _leftPoint;
}
_leftPoint = _point.m_pos
+ _point.m_miterAxe*_width*0.5f;
if (_isStart == false) {
addSegment(_leftPoint, _rightPoint);
SVG_VERBOSE(" segment :" << _leftPoint << " -> " << _rightPoint);
} else {
addSegment(_rightPoint, _leftPoint);
SVG_VERBOSE(" segment :" << _rightPoint << " -> " << _leftPoint);
}
_rightPoint = storeOld;
_rightPoint = _point.m_pos
- _point.m_miterAxe*_width*0.5f;
createSegmentListStroke(_leftPoint,
_rightPoint,
_point.m_pos,
_width,
_isStart);
}
break;
case esvg::cap_square:

View File

@ -28,7 +28,8 @@ namespace esvg {
void createSegmentListStroke(esvg::render::PointList& _listPoint,
float _width,
enum esvg::cap _cap,
enum esvg::join _join);
enum esvg::join _join,
float _miterLimit);
private:
void startStopPoint(vec2& _leftPoint,
vec2& _rightPoint,
@ -36,6 +37,11 @@ namespace esvg {
enum esvg::cap _cap,
float _width,
bool _isStart);
void createSegmentListStroke(const vec2& _point1,
const vec2& _point2,
const vec2& _center,
float _width,
bool _isStart);
};
}
}

View File

@ -12,59 +12,319 @@
#undef __class__
#define __class__ "TestLine"
// ------------------------------------------------------ Miter test -----------------------------------------------------
TEST(TestJoin, miter) {
TEST(TestJoin, miterRight1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,20 50,50 20,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miter.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miter.bmp", g_visualDebug);
etk::FSNodeWriteAllData("TestJoin_miterRight1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterRight1.bmp", g_visualDebug);
}
TEST(TestJoin, roundRight) {
TEST(TestJoin, miterRight2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,80 50,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterRight2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterRight2.bmp", g_visualDebug);
}
TEST(TestJoin, miterRight3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,80 50,50 80,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterRight3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterRight3.bmp", g_visualDebug);
}
TEST(TestJoin, miterRight4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 50,50 20,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterRight4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterRight4.bmp", g_visualDebug);
}
TEST(TestJoin, miterLeft1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 50,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLeft1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLeft1.bmp", g_visualDebug);
}
TEST(TestJoin, miterLeft2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,80 50,50 20,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLeft2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLeft2.bmp", g_visualDebug);
}
TEST(TestJoin, miterLeft3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,80 50,50 20,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLeft3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLeft3.bmp", g_visualDebug);
}
TEST(TestJoin, miterLeft4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,20 50,50 80,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLeft4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLeft4.bmp", g_visualDebug);
}
TEST(TestJoin, miterLimit1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='10,10 25,25 10,40' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLimit1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLimit1.bmp", g_visualDebug);
}
TEST(TestJoin, miterLimit2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='10,10 50,25 10,40' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLimit2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLimit2.bmp", g_visualDebug);
}
TEST(TestJoin, miterLimit3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='10,10 75,25 10,40' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLimit3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLimit3.bmp", g_visualDebug);
}
TEST(TestJoin, miterLimit4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='10,10 90,25 10,40' stroke='green' stroke-width='20' fill='none' stroke-linejoin='miter'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_miterLimit4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_miterLimit4.bmp", g_visualDebug);
}
// ------------------------------------------------------ Round test -----------------------------------------------------
TEST(TestJoin, roundRight1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,20 50,50 20,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundRight.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundRight.bmp", g_visualDebug);
etk::FSNodeWriteAllData("TestJoin_roundRight1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundRight1.bmp", g_visualDebug);
}
TEST(TestJoin, roundLeft) {
TEST(TestJoin, roundRight2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,80 50,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundRight2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundRight2.bmp", g_visualDebug);
}
TEST(TestJoin, roundRight3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,80 50,50 80,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundRight3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundRight3.bmp", g_visualDebug);
}
TEST(TestJoin, roundRight4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 50,50 20,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundRight4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundRight4.bmp", g_visualDebug);
}
TEST(TestJoin, roundLeft1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 50,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundLeft.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundLeft.bmp", g_visualDebug);
etk::FSNodeWriteAllData("TestJoin_roundLeft1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundLeft1.bmp", g_visualDebug);
}
TEST(TestJoin, bevelRight) {
TEST(TestJoin, roundLeft2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,80 50,50 20,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundLeft2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundLeft2.bmp", g_visualDebug);
}
TEST(TestJoin, roundLeft3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,80 50,50 20,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundLeft3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundLeft3.bmp", g_visualDebug);
}
TEST(TestJoin, roundLeft4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,20 50,50 80,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='round'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_roundLeft4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_roundLeft4.bmp", g_visualDebug);
}
// ------------------------------------------------------ Bevel test -----------------------------------------------------
TEST(TestJoin, bevelRight1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,20 50,50 20,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelRight.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelRight.bmp", g_visualDebug);
etk::FSNodeWriteAllData("TestJoin_bevelRight1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelRight1.bmp", g_visualDebug);
}
TEST(TestJoin, bevelLeft) {
TEST(TestJoin, bevelRight2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 60,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
" <polyline points='20,80 50,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelLeft.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelLeft.bmp", g_visualDebug);
}
etk::FSNodeWriteAllData("TestJoin_bevelRight2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelRight2.bmp", g_visualDebug);
}
TEST(TestJoin, bevelRight3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,80 50,50 80,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelRight3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelRight3.bmp", g_visualDebug);
}
TEST(TestJoin, bevelRight4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 50,50 20,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelRight4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelRight4.bmp", g_visualDebug);
}
TEST(TestJoin, bevelLeft1) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,20 50,50 80,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelLeft1.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelLeft1.bmp", g_visualDebug);
}
TEST(TestJoin, bevelLeft2) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='80,80 50,50 20,80' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelLeft2.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelLeft2.bmp", g_visualDebug);
}
TEST(TestJoin, bevelLeft3) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,80 50,50 20,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelLeft3.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelLeft3.bmp", g_visualDebug);
}
TEST(TestJoin, bevelLeft4) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polyline points='20,20 50,50 80,20' stroke='green' stroke-width='20' fill='none' stroke-linejoin='bevel'/>"
"</svg>");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestJoin_bevelLeft4.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestJoin_bevelLeft4.bmp", g_visualDebug);
}