[DEV] correct the with of the path and the good closing of a path

This commit is contained in:
Edouard DUPIN 2015-11-25 21:52:27 +01:00
parent 6925a59c64
commit eca4520384
11 changed files with 96 additions and 15 deletions

View File

@ -112,7 +112,10 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -117,7 +117,10 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -85,7 +85,10 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -279,7 +279,10 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentStroke);
}

View File

@ -98,7 +98,10 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -95,7 +95,10 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -112,7 +112,10 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& 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
tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),

View File

@ -28,6 +28,10 @@ namespace esvg {
vec2 m_pos; //!< position of the point
enum esvg::render::Point::type m_type;
vec2 m_miterAxe;
vec2 m_orthoAxePrevious;
vec2 m_orthoAxeNext;
vec2 m_posPrevious;
vec2 m_posNext;
vec2 m_delta;
float m_len;
Point(const vec2& _pos, enum esvg::render::Point::type _type = esvg::render::Point::type_join) :

View File

@ -43,12 +43,32 @@ void esvg::render::SegmentList::createSegmentList(const esvg::render::PointList&
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) {
// generate for every point all the orthogonal elements
//
// normal edge * end path
// * | * * * * * * * * * * * * * *
// (mitter) * | * * * * * * * * * * * * * *
// * |<--*----this | *
// * | * this -->| *
// * * * | *
@ -93,19 +113,33 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
vecC.safeNormalize();
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);
} 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;
vecB.safeNormalize();
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) {
if (idPevious < 0 ) {
SVG_ERROR("an error occure a previous ID is < 0.... ");
continue;
}
itListPoint[idCurrent].m_posPrevious = itListPoint[idPevious].m_pos;
vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
vecA.safeNormalize();
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 {
SVG_TODO("lklklklklkl");
}
@ -119,10 +153,14 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
// cyclic path...
if ( itListPoint.back().m_type == esvg::render::Point::type_join
|| itListPoint.back().m_type == esvg::render::Point::type_interpolation) {
// Calculate the perpendiculary axis ...
leftPoint = itListPoint.back().m_pos
+ itListPoint.back().m_miterAxe*_width*0.5f;
+ itListPoint.back().m_orthoAxePrevious*_width*0.5f;
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 {
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);
}
haveStartLine = true;
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
leftPoint = it.m_pos
+ it.m_miterAxe*_width*0.5f;
rightPoint = it.m_pos
@ -160,7 +197,6 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
break;
}
haveStartLine = false;
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
vec2 left = it.m_pos
+ it.m_miterAxe*_width*0.5f;
vec2 right = it.m_pos
@ -173,7 +209,11 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
leftPoint = left;
rightPoint = right;
// end line ...
addSegment(rightPoint, leftPoint);
if (rightPoint.y() <= leftPoint.y()) {
addSegment(leftPoint, rightPoint);
} else {
addSegment(rightPoint, leftPoint);
}
SVG_VERBOSE(" segment :" << rightPoint << " -> " << leftPoint);
}
break;
@ -181,10 +221,15 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
{
SVG_VERBOSE("Find interpolation " << it.m_pos);
// 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
+ it.m_miterAxe*_width*0.5f;
vec2 right = it.m_pos
- it.m_miterAxe*_width*0.5f;
#endif
//Draw from previous point:
addSegment(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);
// 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
+ it.m_miterAxe*_width*0.5f;
vec2 right = it.m_pos
- it.m_miterAxe*_width*0.5f;
#endif
//Draw from previous point:
addSegment(leftPoint, left);
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);

View File

@ -11,6 +11,8 @@
#include <etk/types.h>
#include <etk/math/Vector2D.h>
#include <esvg/cap.h>
#include <esvg/join.h>
#include <esvg/render/Segment.h>
#include <esvg/render/PointList.h>
@ -23,7 +25,10 @@ namespace esvg {
SegmentList();
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1);
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);
};
}
}

View File

@ -11,6 +11,7 @@
#include <etk/types.h>
#include <etk/math/Vector2D.h>
#include <esvg/Base.h>
#include <esvg/render/Scanline.h>
#include <esvg/render/SegmentList.h>