From bbfe108c5b4de905cae89cf3ed9c88d0a4383e21 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 20 Nov 2015 21:34:09 +0100 Subject: [PATCH] [DEV] multiple add: - add display debug to faster developpement - add multiple line path in the pointing list - better integration of conficuration of svg parameter --- esvg/Base.h | 2 +- esvg/Path.cpp | 28 +- esvg/Polyline.cpp | 3 + esvg/Rectangle.cpp | 33 ++- esvg/Renderer.cpp | 178 ++++++++++-- esvg/Renderer.h | 48 +++- esvg/esvg.cpp | 4 +- esvg/esvg.h | 2 +- esvg/render/Element.cpp | 7 + esvg/render/Element.h | 2 + esvg/render/ElementBezierCurveTo.cpp | 2 + esvg/render/ElementBezierSmoothCurveTo.cpp | 2 + esvg/render/ElementClose.cpp | 25 ++ esvg/render/ElementClose.h | 28 ++ esvg/render/ElementCurveTo.cpp | 2 + esvg/render/ElementElliptic.cpp | 2 + esvg/render/ElementLineTo.cpp | 2 + esvg/render/ElementLineToH.cpp | 2 + esvg/render/ElementLineToV.cpp | 2 + esvg/render/ElementMoveTo.cpp | 3 +- esvg/render/ElementSmoothCurveTo.cpp | 2 + esvg/render/ElementStop.cpp | 6 +- esvg/render/ElementStop.h | 2 +- esvg/render/Path.cpp | 122 ++++----- esvg/render/Path.h | 7 +- esvg/render/Point.cpp | 2 + esvg/render/PointList.cpp | 48 ++++ esvg/render/PointList.h | 31 +++ esvg/render/Scanline.cpp | 3 + esvg/render/Segment.cpp | 2 + esvg/render/SegmentList.cpp | 304 +++++++++++---------- esvg/render/SegmentList.h | 6 +- esvg/render/Weight.cpp | 3 + lutin_esvg.py | 4 + test/main.cpp | 23 ++ test/main.h | 17 ++ test/testCircle.cpp | 10 +- test/testEllipse.cpp | 10 +- test/testLine.cpp | 6 +- test/testPath.cpp | 18 +- test/testPolygon.cpp | 10 +- test/testRectangle.cpp | 16 +- 42 files changed, 706 insertions(+), 323 deletions(-) create mode 100644 esvg/render/ElementClose.cpp create mode 100644 esvg/render/ElementClose.h create mode 100644 esvg/render/PointList.cpp create mode 100644 esvg/render/PointList.h create mode 100644 test/main.h diff --git a/esvg/Base.h b/esvg/Base.h index 377c679..15cd5d0 100644 --- a/esvg/Base.h +++ b/esvg/Base.h @@ -70,7 +70,7 @@ namespace esvg { Base(PaintState _parentPaintState); virtual ~Base() { }; virtual bool parse(const std::shared_ptr& _element, mat2& _parentTrans, vec2& _sizeMax); - //specific drawing for AAG librairy ... + virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level=1); virtual void display(int32_t _spacing) { }; diff --git a/esvg/Path.cpp b/esvg/Path.cpp index f2e7e24..91498a6 100644 --- a/esvg/Path.cpp +++ b/esvg/Path.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #undef __class__ @@ -239,7 +240,7 @@ bool esvg::Path::parse(const std::shared_ptr& _element, mat2& _pa SVG_WARNING("the PATH command "<< command << " has not the good number of element = " << listDot.size() ); break; } - m_listElement.stop(relative); + m_listElement.close(relative); break; default: SVG_ERROR ("Unknow error : \"" << command << "\""); @@ -255,36 +256,39 @@ void esvg::Path::display(int32_t _spacing) { void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level) { SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Path"); - int32_t recurtionMax = 10; - float threshold = 0.25f; mat2 mtx = m_transformMatrix; mtx *= _basicTrans; - std::vector listPoints = m_listElement.generateListPoints(_level, recurtionMax, threshold); - + esvg::render::PointList listPoints; + listPoints = m_listElement.generateListPoints(_level, + _myRenderer.getInterpolationRecurtionMax(), + _myRenderer.getInterpolationThreshold()); + esvg::render::SegmentList listSegmentFill; + esvg::render::SegmentList listSegmentStroke; esvg::render::Weight tmpFill; esvg::render::Weight tmpStroke; // Check if we need to display background - int32_t nbSubScanLine = 8; if (m_paint.fill.a() != 0x00) { - esvg::render::SegmentList listSegment; - listSegment.createSegmentList(listPoints); + listSegmentFill.createSegmentList(listPoints); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - tmpFill.generate(ivec2(128,128), nbSubScanLine, listSegment); + tmpFill.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentFill); } // check if we need to display stroke: if ( m_paint.strokeWidth > 0 && m_paint.stroke.a() != 0x00) { - esvg::render::SegmentList listSegment; - listSegment.createSegmentListStroke(listPoints); + listSegmentStroke.createSegmentListStroke(listPoints); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - tmpStroke.generate(ivec2(128,128), nbSubScanLine, listSegment); + tmpStroke.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentStroke); } // add on images: _myRenderer.print(tmpFill, m_paint.fill, tmpStroke, m_paint.stroke); + #ifdef DEBUG + _myRenderer.addDebugSegment(listSegmentFill); + _myRenderer.addDebugSegment(listSegmentStroke); + #endif } diff --git a/esvg/Polyline.cpp b/esvg/Polyline.cpp index 5a708fc..f00b8b6 100644 --- a/esvg/Polyline.cpp +++ b/esvg/Polyline.cpp @@ -9,6 +9,9 @@ #include #include +#undef __class__ +#define __class__ "Polyline" + esvg::Polyline::Polyline(PaintState _parentPaintState) : esvg::Base(_parentPaintState) { } diff --git a/esvg/Rectangle.cpp b/esvg/Rectangle.cpp index 8c33ee5..e584314 100644 --- a/esvg/Rectangle.cpp +++ b/esvg/Rectangle.cpp @@ -67,39 +67,44 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32 listElement.lineToH(true, m_size.x()); listElement.lineToV(true, m_size.y()); listElement.lineToH(true, -m_size.x()); - listElement.lineToV(true, -m_size.y()); - listElement.stop(); - - int32_t recurtionMax = 10; - float threshold = 0.25f; + listElement.close(); mat2 mtx = m_transformMatrix; mtx *= _basicTrans; - std::vector listPoints = listElement.generateListPoints(_level, recurtionMax, threshold); - + esvg::render::PointList listPoints; + listPoints = listElement.generateListPoints(_level, + _myRenderer.getInterpolationRecurtionMax(), + _myRenderer.getInterpolationThreshold()); + esvg::render::SegmentList listSegmentFill; + esvg::render::SegmentList listSegmentStroke; esvg::render::Weight tmpFill; esvg::render::Weight tmpStroke; // Check if we need to display background - int32_t nbSubScanLine = 8; if (m_paint.fill.a() != 0x00) { - esvg::render::SegmentList listSegment; - listSegment.createSegmentList(listPoints); + listSegmentFill.createSegmentList(listPoints); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - tmpFill.generate(ivec2(128,128), nbSubScanLine, listSegment); + tmpFill.generate(_myRenderer.getSize(), + _myRenderer.getNumberSubScanLine(), + listSegmentFill); } // check if we need to display stroke: if ( m_paint.strokeWidth > 0 && m_paint.stroke.a() != 0x00) { - esvg::render::SegmentList listSegment; - listSegment.createSegmentListStroke(listPoints); + listSegmentStroke.createSegmentListStroke(listPoints); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - tmpStroke.generate(ivec2(128,128), nbSubScanLine, listSegment); + tmpStroke.generate(_myRenderer.getSize(), + _myRenderer.getNumberSubScanLine(), + listSegmentStroke); } // add on images: _myRenderer.print(tmpFill, m_paint.fill, tmpStroke, m_paint.stroke); + #ifdef DEBUG + _myRenderer.addDebugSegment(listSegmentFill); + _myRenderer.addDebugSegment(listSegmentStroke); + #endif } diff --git a/esvg/Renderer.cpp b/esvg/Renderer.cpp index f833f67..f70afd1 100644 --- a/esvg/Renderer.cpp +++ b/esvg/Renderer.cpp @@ -15,14 +15,22 @@ #undef __class__ #define __class__ "Renderer" -esvg::Renderer::Renderer(const ivec2& _size) { - m_size = _size; - m_buffer.resize(m_size.x() * m_size.y() * DATA_ALLOCATION_ELEMENT, 0); +esvg::Renderer::Renderer(const ivec2& _size, bool _visualDebug) : +#ifdef DEBUG + m_visualDebug(_visualDebug), + m_factor(1), +#endif + m_interpolationRecurtionMax(10), + m_interpolationThreshold(0.25f), + m_nbSubScanLine(8) { + if (m_visualDebug == true) { + m_factor = 10; + } + setSize(_size); } esvg::Renderer::~Renderer() { m_buffer.clear(); - m_stride = 0; m_size = ivec2(0,0); } @@ -30,18 +38,28 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill, const etk::Color& _colorFill, const esvg::render::Weight& _weightStroke, const etk::Color& _colorStroke) { + int32_t sizeX = m_size.x(); + int32_t sizeY = m_size.y(); + #if DEBUG + sizeX *= m_factor; + sizeY *= m_factor; + #endif if (_colorFill.a() == 0x00) { if (_colorStroke.a() != 0x00) { // only stroke - for (int32_t yyy=0; yyy availlableSegmentPixel; + for (auto &it : _listSegment.m_data) { + if ( it.p0.y() * m_factor <= float(yyy+1) + && it.p1.y() * m_factor >= float(yyy)) { + availlableSegmentPixel.push_back(it); + } + } + //find all the segment that cross the middle of the line of the center of the pixel line: + float subSamplingCenterPos = yyy + 0.5f; + std::vector availlableSegment; + // find in the subList ... + for (auto &it : availlableSegmentPixel) { + if ( it.p0.y() * m_factor <= subSamplingCenterPos + && it.p1.y() * m_factor >= subSamplingCenterPos) { + availlableSegment.push_back(it); + } + } + // x position, angle + std::vector> listPosition; + for (auto &it : availlableSegment) { + vec2 delta = it.p0 * m_factor - it.p1 * m_factor; + // x = coefficent*y+bbb; + float coefficient = delta.x()/delta.y(); + float bbb = it.p0.x() * m_factor - coefficient*it.p0.y() * m_factor; + float xpos = coefficient * subSamplingCenterPos + bbb; + m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 ] = 0x00; + m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 + 1] = 0x00; + m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 + 2] = 0xFF; + m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 + 3] = 0xFF; + } + } + } +#endif + + // Writing the buffer to a .PPM file, assuming it has // RGB-structure, one byte per color component //-------------------------------------------------- @@ -96,7 +166,11 @@ void esvg::Renderer::writePpm(std::string fileName) { if(fd != nullptr) { int32_t sizeX = m_size.x(); int32_t sizeY = m_size.y(); - SVG_DEBUG("Generate ppm : " << m_size); + #if DEBUG + sizeX *= m_factor; + sizeY *= m_factor; + #endif + SVG_DEBUG("Generate ppm : " << m_size << " debug size=" << ivec2(sizeX,sizeY)); fprintf(fd, "P6 %d %d 255 ", sizeX, sizeY); for (int32_t iii=0 ; iii namespace esvg { - class Renderer { + #ifdef DEBUG + private: + bool m_visualDebug; + int32_t m_factor; + #endif public: - std::vector m_buffer; - ivec2 m_size; - int32_t m_stride; - public: - Renderer(const ivec2& _size); + Renderer(const ivec2& _size, bool _visualDebug=false); ~Renderer(); + protected: + ivec2 m_size; + public: + void setSize(const ivec2& _size); + const ivec2& getSize() const; + protected: + std::vector m_buffer; + public: + uint8_t* getDataPointer(); + uint32_t getDataSize() const; + protected: + int32_t m_interpolationRecurtionMax; + public: + void setInterpolationRecurtionMax(int32_t _value); + int32_t getInterpolationRecurtionMax() const; + protected: + float m_interpolationThreshold; + public: + void setInterpolationThreshold(float _value); + float getInterpolationThreshold() const; + protected: + int32_t m_nbSubScanLine; + public: + void setNumberSubScanLine(int32_t _value); + int32_t getNumberSubScanLine() const; + public: void writePpm(std::string fileName); - uint8_t* getDataPointer() { - return &m_buffer[0]; - }; - uint32_t getDataSize() { - return m_buffer.size(); - }; + public: void print(const esvg::render::Weight& _weightFill, const etk::Color& _colorFill, const esvg::render::Weight& _weightStroke, const etk::Color& _colorStroke); + #ifdef DEBUG + void addDebugSegment(const esvg::render::SegmentList& _listSegment); + #endif }; }; diff --git a/esvg/esvg.cpp b/esvg/esvg.cpp index b5dadcb..1a911e7 100644 --- a/esvg/esvg.cpp +++ b/esvg/esvg.cpp @@ -99,7 +99,7 @@ void esvg::Document::generateTestFile() // FOR TEST only ... -void esvg::Document::generateAnImage(const ivec2& _size, const std::string& _fileName) { +void esvg::Document::generateAnImage(const ivec2& _size, const std::string& _fileName, bool _visualDebug) { int32_t sizeX = _size.x(); if (sizeX == 0) { SVG_ERROR("SizeX == 0 ==> set 64"); @@ -114,7 +114,7 @@ void esvg::Document::generateAnImage(const ivec2& _size, const std::string& _fil delete(m_renderedElement); m_renderedElement = nullptr; - m_renderedElement = new esvg::Renderer(ivec2(sizeX, sizeY)); + m_renderedElement = new esvg::Renderer(ivec2(sizeX, sizeY), _visualDebug); // create the first element matrix modification ... mat2 basicTrans; //basicTrans *= etk::mat2Translate(vec2(-g_base_dx, -g_base_dy)); diff --git a/esvg/esvg.h b/esvg/esvg.h index 42e2908..5278bb2 100644 --- a/esvg/esvg.h +++ b/esvg/esvg.h @@ -68,7 +68,7 @@ namespace esvg { }; void displayDebug(); void generateTestFile(); - void generateAnImage(const ivec2& _size, const std::string& _fileName); + void generateAnImage(const ivec2& _size, const std::string& _fileName, bool _visualDebug=false); //void generateAnImage(ivec2 _size, draw::Image& _output); //void generateAnImage(draw::Image& _output); virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans); diff --git a/esvg/render/Element.cpp b/esvg/render/Element.cpp index 556c16a..d970896 100644 --- a/esvg/render/Element.cpp +++ b/esvg/render/Element.cpp @@ -8,11 +8,18 @@ #include #include + +#undef __class__ +#define __class__ "rerder::Element" + std::ostream& esvg::operator <<(std::ostream& _os, enum esvg::render::path _obj) { switch (_obj) { case esvg::render::path_stop: _os << "path_stop"; break; + case esvg::render::path_close: + _os << "path_close"; + break; case esvg::render::path_moveTo: _os << "path_moveTo"; break; diff --git a/esvg/render/Element.h b/esvg/render/Element.h index d6f7b3d..9cd0c3f 100644 --- a/esvg/render/Element.h +++ b/esvg/render/Element.h @@ -16,6 +16,7 @@ namespace esvg { namespace render { enum path { path_stop, + path_close, path_moveTo, path_lineTo, path_lineToH, @@ -93,6 +94,7 @@ namespace esvg { #endif #include +#include #include #include #include diff --git a/esvg/render/ElementBezierCurveTo.cpp b/esvg/render/ElementBezierCurveTo.cpp index 947959f..4b2bcac 100644 --- a/esvg/render/ElementBezierCurveTo.cpp +++ b/esvg/render/ElementBezierCurveTo.cpp @@ -9,6 +9,8 @@ #include #include +#undef __class__ +#define __class__ "rerder::ElementBezierCurveTo" esvg::render::ElementBezierCurveTo::ElementBezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos): diff --git a/esvg/render/ElementBezierSmoothCurveTo.cpp b/esvg/render/ElementBezierSmoothCurveTo.cpp index 5551c25..b200efc 100644 --- a/esvg/render/ElementBezierSmoothCurveTo.cpp +++ b/esvg/render/ElementBezierSmoothCurveTo.cpp @@ -10,6 +10,8 @@ #include +#undef __class__ +#define __class__ "rerder::ElementBezierSmoothCurveTo" esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos): Element(esvg::render::path_bezierSmoothCurveTo, _relative) { diff --git a/esvg/render/ElementClose.cpp b/esvg/render/ElementClose.cpp new file mode 100644 index 0000000..4ed6d0c --- /dev/null +++ b/esvg/render/ElementClose.cpp @@ -0,0 +1,25 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include + + +#undef __class__ +#define __class__ "rerder::ElementClose" + +esvg::render::ElementClose::ElementClose(bool _relative): + Element(esvg::render::path_close, _relative) { + +} + +std::string esvg::render::ElementClose::display() const { + return ""; +} + + diff --git a/esvg/render/ElementClose.h b/esvg/render/ElementClose.h new file mode 100644 index 0000000..19fb583 --- /dev/null +++ b/esvg/render/ElementClose.h @@ -0,0 +1,28 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#ifndef __ESVG_RENDER_ELEMENT_CLOSE_H__ +#define __ESVG_RENDER_ELEMENT_CLOSE_H__ + +#include +#include +#include + +namespace esvg { + namespace render { + class ElementClose : public esvg::render::Element { + public: + ElementClose(bool _relative=false); + public: + virtual std::string display() const; + }; + } +} + +#endif + diff --git a/esvg/render/ElementCurveTo.cpp b/esvg/render/ElementCurveTo.cpp index 0f7e83f..fb229c1 100644 --- a/esvg/render/ElementCurveTo.cpp +++ b/esvg/render/ElementCurveTo.cpp @@ -9,6 +9,8 @@ #include #include +#undef __class__ +#define __class__ "rerder::ElementCurveTo" esvg::render::ElementCurveTo::ElementCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos): diff --git a/esvg/render/ElementElliptic.cpp b/esvg/render/ElementElliptic.cpp index 7c48da8..eb57f8c 100644 --- a/esvg/render/ElementElliptic.cpp +++ b/esvg/render/ElementElliptic.cpp @@ -10,6 +10,8 @@ #include +#undef __class__ +#define __class__ "rerder::ElementElliptic" esvg::render::ElementElliptic::ElementElliptic(bool _relative, const vec2& _radius, // in m_vec1 diff --git a/esvg/render/ElementLineTo.cpp b/esvg/render/ElementLineTo.cpp index bcad04c..cbe3a74 100644 --- a/esvg/render/ElementLineTo.cpp +++ b/esvg/render/ElementLineTo.cpp @@ -10,6 +10,8 @@ #include +#undef __class__ +#define __class__ "rerder::ElementLineTo" esvg::render::ElementLineTo::ElementLineTo(bool _relative, const vec2& _pos): Element(esvg::render::path_lineTo, _relative) { diff --git a/esvg/render/ElementLineToH.cpp b/esvg/render/ElementLineToH.cpp index 55e8223..2fb2ada 100644 --- a/esvg/render/ElementLineToH.cpp +++ b/esvg/render/ElementLineToH.cpp @@ -9,6 +9,8 @@ #include #include +#undef __class__ +#define __class__ "rerder::ElementLineToH" esvg::render::ElementLineToH::ElementLineToH(bool _relative, float _posX): diff --git a/esvg/render/ElementLineToV.cpp b/esvg/render/ElementLineToV.cpp index 8f1fceb..7623f33 100644 --- a/esvg/render/ElementLineToV.cpp +++ b/esvg/render/ElementLineToV.cpp @@ -9,6 +9,8 @@ #include #include +#undef __class__ +#define __class__ "rerder::ElementLineToV" esvg::render::ElementLineToV::ElementLineToV(bool _relative, float _posY): diff --git a/esvg/render/ElementMoveTo.cpp b/esvg/render/ElementMoveTo.cpp index 65ede7d..aae2989 100644 --- a/esvg/render/ElementMoveTo.cpp +++ b/esvg/render/ElementMoveTo.cpp @@ -9,7 +9,8 @@ #include #include - +#undef __class__ +#define __class__ "rerder::ElementMoveTo" esvg::render::ElementMoveTo::ElementMoveTo(bool _relative, const vec2& _pos): Element(esvg::render::path_moveTo, _relative) { diff --git a/esvg/render/ElementSmoothCurveTo.cpp b/esvg/render/ElementSmoothCurveTo.cpp index 7288ed7..88e8d65 100644 --- a/esvg/render/ElementSmoothCurveTo.cpp +++ b/esvg/render/ElementSmoothCurveTo.cpp @@ -10,6 +10,8 @@ #include +#undef __class__ +#define __class__ "rerder::ElementSmoothCurveTo" esvg::render::ElementSmoothCurveTo::ElementSmoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos): Element(esvg::render::path_smoothCurveTo, _relative) { diff --git a/esvg/render/ElementStop.cpp b/esvg/render/ElementStop.cpp index 0b6e815..e806a37 100644 --- a/esvg/render/ElementStop.cpp +++ b/esvg/render/ElementStop.cpp @@ -10,9 +10,11 @@ #include +#undef __class__ +#define __class__ "rerder::ElementStop" -esvg::render::ElementStop::ElementStop(bool _relative): - Element(esvg::render::path_stop, _relative) { +esvg::render::ElementStop::ElementStop(): + Element(esvg::render::path_stop) { } diff --git a/esvg/render/ElementStop.h b/esvg/render/ElementStop.h index e3d5776..75d9d15 100644 --- a/esvg/render/ElementStop.h +++ b/esvg/render/ElementStop.h @@ -17,7 +17,7 @@ namespace esvg { namespace render { class ElementStop : public esvg::render::Element { public: - ElementStop(bool _relative=false); + ElementStop(); public: virtual std::string display() const; }; diff --git a/esvg/render/Path.cpp b/esvg/render/Path.cpp index f3e4231..fc28648 100644 --- a/esvg/render/Path.cpp +++ b/esvg/render/Path.cpp @@ -9,12 +9,19 @@ #include #include +#undef __class__ +#define __class__ "rerder::Path" + void esvg::render::Path::clear() { m_listElement.clear(); } -void esvg::render::Path::stop(bool _relative) { - m_listElement.push_back(std::make_shared(_relative)); +void esvg::render::Path::stop() { + m_listElement.push_back(std::make_shared()); +} + +void esvg::render::Path::close(bool _relative) { + m_listElement.push_back(std::make_shared(_relative)); } void esvg::render::Path::moveTo(bool _relative, const vec2& _pos) { @@ -109,34 +116,10 @@ void interpolateCubicBezier(std::vector& _listPoint, interpolateCubicBezier(_listPoint, _recurtionMax, _threshold, pos1234, pos234, pos34, _pos4, _level+1, _type); } -void diplayRenderPoints(const std::vector& listPoints) { - SVG_VERBOSE(" Display list of points : size=" << listPoints.size()); - for (int32_t iii=0; - iii < listPoints.size(); - ++iii) { - switch (listPoints[iii].m_type) { - case esvg::render::Point::type_single: - SVG_VERBOSE(" [" << iii << "] Find Single " << listPoints[iii].m_pos); - break; - case esvg::render::Point::type_start: - SVG_VERBOSE(" [" << iii << "] Find Start " << listPoints[iii].m_pos); - break; - case esvg::render::Point::type_stop: - SVG_VERBOSE(" [" << iii << "] Find Stop " << listPoints[iii].m_pos); - break; - case esvg::render::Point::type_interpolation: - SVG_VERBOSE(" [" << iii << "] Find interpolation " << listPoints[iii].m_pos); - break; - case esvg::render::Point::type_join: - SVG_VERBOSE(" [" << iii << "] Find Join " << listPoints[iii].m_pos); - break; - } - } -} - -std::vector esvg::render::Path::generateListPoints(int32_t _level, int32_t _recurtionMax, float _threshold) { +esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, int32_t _recurtionMax, float _threshold) { SVG_VERBOSE(spacingDist(_level) << "Generate List Points ... from a path"); - std::vector out; + esvg::render::PointList out; + std::vector tmpListPoint; vec2 lastPosition(0.0f, 0.0f); int32_t lastPointId = -1; bool PathStart = false; @@ -145,82 +128,84 @@ std::vector esvg::render::Path::generateListPoints(int32_t if (it == nullptr) { continue; } + SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); switch (it->getType()) { case esvg::render::path_stop: - SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); - // TODO : Check if the z value mean that the path will cycle ... - if (out.size() != 0) { - if (PathStart == false) { + if (tmpListPoint.size() != 0) { + if (tmpListPoint.size() == 0) { SVG_WARNING(spacingDist(_level+1) << " Request path stop of not starting path ..."); } else { - out.back().setEndPath(); - PathStart = false; + tmpListPoint.back().setEndPath(); + out.addList(tmpListPoint); + tmpListPoint.clear(); + } + } + // nothing alse to do ... + break; + case esvg::render::path_close: + if (tmpListPoint.size() != 0) { + if (tmpListPoint.size() == 0) { + SVG_WARNING(spacingDist(_level+1) << " Request path close of not starting path ..."); + } else { + // find the previous tart of the path ... + tmpListPoint.front().m_type = esvg::render::Point::type_join; + out.addList(tmpListPoint); + tmpListPoint.clear(); } } // nothing alse to do ... break; case esvg::render::path_moveTo: - SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); // stop last path - if (out.size() != 0) { - if (PathStart == true) { - out.back().setEndPath(); - PathStart = false; - } + if (tmpListPoint.size() != 0) { + tmpListPoint.back().setEndPath(); + out.addList(tmpListPoint); + tmpListPoint.clear(); } - PathStart = true; // create a new one if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); break; case esvg::render::path_lineTo: - SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); // If no previous point, we need to create the last point has start ... - if (PathStart == false) { - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); - PathStart = true; + if (tmpListPoint.size() == 0) { + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); } if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); break; case esvg::render::path_lineToH: - SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); // If no previous point, we need to create the last point has start ... - if (PathStart == false) { - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); - PathStart = true; + if (tmpListPoint.size() == 0) { + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); } if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); break; case esvg::render::path_lineToV: - SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); // If no previous point, we need to create the last point has start ... - if (PathStart == false) { - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); - PathStart = true; + if (tmpListPoint.size() == 0) { + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); } if (it->getRelative() == false) { lastPosition = vec2(0.0f, 0.0f); } lastPosition += it->getPos(); - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); break; case esvg::render::path_curveTo: - SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); // If no previous point, we need to create the last point has start ... - if (PathStart == false) { - out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); - PathStart = true; + if (tmpListPoint.size() == 0) { + tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); } { vec2 lastPosStore(lastPosition); @@ -230,7 +215,7 @@ std::vector esvg::render::Path::generateListPoints(int32_t vec2 pos1 = lastPosition + it->getPos1();; vec2 pos2 = lastPosition + it->getPos2();; vec2 pos = lastPosition + it->getPos();; - interpolateCubicBezier(out, + interpolateCubicBezier(tmpListPoint, _recurtionMax, _threshold, lastPosStore, @@ -243,7 +228,6 @@ std::vector esvg::render::Path::generateListPoints(int32_t } break; case esvg::render::path_smoothCurveTo: - SVG_TODO(spacingDist(_level+1) << " Draw : " << *it); /* path.curve4SmoothTo(it->getRelative(), vec2(it->m_element[0], @@ -253,7 +237,6 @@ std::vector esvg::render::Path::generateListPoints(int32_t */ break; case esvg::render::path_bezierCurveTo: - SVG_TODO(spacingDist(_level+1) << " Draw : " << *it); /* path.curve3To(it->getRelative(), vec2(it->m_element[0], @@ -263,7 +246,6 @@ std::vector esvg::render::Path::generateListPoints(int32_t */ break; case esvg::render::path_bezierSmoothCurveTo: - SVG_TODO(spacingDist(_level+1) << " Draw : " << *it); /* path.curve3SmoothTo(it->getRelative(), vec2(it->m_element[0], @@ -282,13 +264,17 @@ std::vector esvg::render::Path::generateListPoints(int32_t it->m_element[5], it->m_element[6] ); */ - SVG_TODO(spacingDist(_level+1) << " Draw : " << *it); break; default: SVG_ERROR(spacingDist(_level+1) << " Unknow PATH commant (internal error)"); break; } } - diplayRenderPoints(out); + if (tmpListPoint.size() != 0) { + SVG_WARNING("TODO ... check this ..."); + out.addList(tmpListPoint); + tmpListPoint.clear(); + } + out.display(); return out; } \ No newline at end of file diff --git a/esvg/render/Path.h b/esvg/render/Path.h index 3a7b544..387c5b5 100644 --- a/esvg/render/Path.h +++ b/esvg/render/Path.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include namespace esvg { @@ -29,7 +29,8 @@ namespace esvg { } void clear(); - void stop(bool _relative=false); + void stop(); + void close(bool _relative=false); void moveTo(bool _relative, const vec2& _pos); void lineTo(bool _relative, const vec2& _pos); void lineToH(bool _relative, float _posX); @@ -45,7 +46,7 @@ namespace esvg { bool _sweepFlag, const vec2& _pos); void display(int32_t _spacing); - std::vector generateListPoints(int32_t _level, int32_t _recurtionMax = 10, float _threshold = 0.25f); + esvg::render::PointList generateListPoints(int32_t _level, int32_t _recurtionMax = 10, float _threshold = 0.25f); }; } } diff --git a/esvg/render/Point.cpp b/esvg/render/Point.cpp index 844f2ea..8cd475b 100644 --- a/esvg/render/Point.cpp +++ b/esvg/render/Point.cpp @@ -9,6 +9,8 @@ #include #include +#undef __class__ +#define __class__ "rerder::Point" void esvg::render::Point::setEndPath() { if (m_type == esvg::render::Point::type_interpolation) { diff --git a/esvg/render/PointList.cpp b/esvg/render/PointList.cpp new file mode 100644 index 0000000..02ce058 --- /dev/null +++ b/esvg/render/PointList.cpp @@ -0,0 +1,48 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include + +esvg::render::PointList::PointList() { + // nothing to do ... +} + +void esvg::render::PointList::addList(std::vector& _list) { + m_data.push_back(_list); + // TODO : Add a checker of correct list ... +} + + +void esvg::render::PointList::display() { + SVG_VERBOSE(" Display list of points : size=" << m_data.size()); + for (auto &it : m_data) { + SVG_VERBOSE(" Find List " << it.size() << " members"); + for (int32_t iii=0; + iii < it.size(); + ++iii) { + switch (it[iii].m_type) { + case esvg::render::Point::type_single: + SVG_VERBOSE(" [" << iii << "] Find Single " << it[iii].m_pos); + break; + case esvg::render::Point::type_start: + SVG_VERBOSE(" [" << iii << "] Find Start " << it[iii].m_pos); + break; + case esvg::render::Point::type_stop: + SVG_VERBOSE(" [" << iii << "] Find Stop " << it[iii].m_pos); + break; + case esvg::render::Point::type_interpolation: + SVG_VERBOSE(" [" << iii << "] Find interpolation " << it[iii].m_pos); + break; + case esvg::render::Point::type_join: + SVG_VERBOSE(" [" << iii << "] Find Join " << it[iii].m_pos); + break; + } + } + } +} diff --git a/esvg/render/PointList.h b/esvg/render/PointList.h new file mode 100644 index 0000000..000668e --- /dev/null +++ b/esvg/render/PointList.h @@ -0,0 +1,31 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#ifndef __ESVG_RENDER_POINT_LIST_H__ +#define __ESVG_RENDER_POINT_LIST_H__ + +#include +#include +#include +#include + +namespace esvg { + namespace render { + class PointList { + public: + std::vector> m_data; + public: + PointList(); + void addList(std::vector& _list); + void display(); + }; + } +} + +#endif + diff --git a/esvg/render/Scanline.cpp b/esvg/render/Scanline.cpp index 5f004f9..92cc571 100644 --- a/esvg/render/Scanline.cpp +++ b/esvg/render/Scanline.cpp @@ -9,6 +9,9 @@ #include #include +#undef __class__ +#define __class__ "rerder::Scanline" + esvg::render::Scanline::Scanline(size_t _size) { float tmp(0); m_data.resize(_size, tmp); diff --git a/esvg/render/Segment.cpp b/esvg/render/Segment.cpp index c20a8e2..ce5a35a 100644 --- a/esvg/render/Segment.cpp +++ b/esvg/render/Segment.cpp @@ -9,6 +9,8 @@ #include #include +#undef __class__ +#define __class__ "rerder::Segment" esvg::render::Segment::Segment(const vec2& _p0, const vec2& _p1) { // segment register all time the lower at P0n then we need to register the sens of the path diff --git a/esvg/render/SegmentList.cpp b/esvg/render/SegmentList.cpp index 282f434..343cedb 100644 --- a/esvg/render/SegmentList.cpp +++ b/esvg/render/SegmentList.cpp @@ -10,6 +10,9 @@ #include +#undef __class__ +#define __class__ "rerder::SegmentList" + bool sortSegmentFunction(const esvg::render::Segment& _e1, const esvg::render::Segment& _e2) { return _e1.p0.y() < _e2.p0.y(); } @@ -27,163 +30,174 @@ void esvg::render::SegmentList::addSegment(const esvg::render::Point& _pos0, con m_data.push_back(Segment(_pos0.m_pos, _pos1.m_pos)); } -void esvg::render::SegmentList::createSegmentList(const std::vector& _listPoint) { - // Build Segments - for (int32_t iii=0, jjj=_listPoint.size()-1; - iii < _listPoint.size(); - jjj = iii++) { - addSegment(_listPoint[jjj], _listPoint[iii]); +void esvg::render::SegmentList::createSegmentList(const esvg::render::PointList& _listPoint) { + for (auto &it : _listPoint.m_data) { + // Build Segments + for (int32_t iii=0, jjj=it.size()-1; + iii < it.size(); + jjj = iii++) { + addSegment(it[jjj], it[iii]); + } } // TODO : Check if it is really usefull ... std::sort(m_data.begin(), m_data.end(), sortSegmentFunction); } -void esvg::render::SegmentList::createSegmentListStroke(std::vector& _listPoint) { - // generate for every point all the orthogonal elements - // normal edge * end path - // * | * * * * * * * * * * * * * * - // * |<--*----this | * - // * | * this -->| * - // * * * | * - // * . | . * . . . . . . . . * * - // * . | . * | * - // * A . | . B * | * - // . * . | * - // . * * . * * * * * * * * * * * * * - // * * - // * * - // TODO : Start and stop of the path ... - for (int32_t idPevious=-1, idCurrent=0, idNext=1; - idCurrent < _listPoint.size(); - idPevious++, idCurrent++, idNext++) { - if ( _listPoint[idCurrent].m_type == esvg::render::Point::type_join - || _listPoint[idCurrent].m_type == esvg::render::Point::type_interpolation) { - if (idPevious < 0 ) { - SVG_ERROR("an error occure a previous ID is < 0.... "); - continue; +void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& _listPoint) { + for (auto &itListPoint : _listPoint.m_data) { + // generate for every point all the orthogonal elements + // normal edge * end path + // * | * * * * * * * * * * * * * * + // * |<--*----this | * + // * | * this -->| * + // * * * | * + // * . | . * . . . . . . . . * * + // * . | . * | * + // * A . | . B * | * + // . * . | * + // . * * . * * * * * * * * * * * * * + // * * + // * * + // TODO : Start and stop of the path ... + for (int32_t idPevious=itListPoint.size()-1, idCurrent=0, idNext=1; + idCurrent < itListPoint.size(); + idPevious = idCurrent++, idNext++) { + if (idNext == itListPoint.size()) { + idNext = 0; } - if (idNext >= _listPoint.size()) { - SVG_ERROR("an error occure a next ID is >= nbPoint len .... "); - continue; - } - vec2 vecA = _listPoint[idCurrent].m_pos - _listPoint[idPevious].m_pos; - vecA.safeNormalize(); - vec2 vecB = _listPoint[idNext].m_pos - _listPoint[idCurrent].m_pos; - vecB.safeNormalize(); - vec2 vecC = vecA - vecB; - if (vecC == vec2(0,0)) { - // special case: 1 line ... - _listPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x()); + if ( itListPoint[idCurrent].m_type == esvg::render::Point::type_join + || itListPoint[idCurrent].m_type == esvg::render::Point::type_interpolation) { + if (idPevious < 0 ) { + SVG_ERROR("an error occure a previous ID is < 0.... "); + continue; + } + if (idNext >= itListPoint.size()) { + SVG_ERROR("an error occure a next ID is >= nbPoint len .... "); + continue; + } + SVG_DEBUG("JOIN : id : prev/curr/next : " << idPevious << "/" << idCurrent << "/" << idNext); + SVG_DEBUG("JOIN : val : prev/curr/next : " << itListPoint[idPevious].m_pos << "/" << itListPoint[idCurrent].m_pos << "/" << itListPoint[idNext].m_pos); + vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos; + SVG_DEBUG("JOIN : vecA : " << vecA); + vecA.safeNormalize(); + vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos; + SVG_DEBUG("JOIN : vecB : " << vecB); + vecB.safeNormalize(); + vec2 vecC = vecA - vecB; + SVG_DEBUG("JOIN : vecC : " << vecC); + if (vecC == vec2(0.0f, 0.0f)) { + // special case: 1 line ... + itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x()); + } else { + vecC.safeNormalize(); + itListPoint[idCurrent].m_miterAxe = vecC; + } + SVG_DEBUG("JOIN : miterAxe " << itListPoint[idCurrent].m_miterAxe); + } else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_start) { + vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos; + vecB.safeNormalize(); + itListPoint[idCurrent].m_miterAxe = vec2(vecB.y(), vecB.x()); + } 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; + } + vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos; + vecA.safeNormalize(); + itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x()); } else { - vecC.safeNormalize(); - _listPoint[idCurrent].m_miterAxe = vecC; + SVG_TODO("lklklklklkl"); } - } else if (_listPoint[idCurrent].m_type == esvg::render::Point::type_start) { - vec2 vecB = _listPoint[idNext].m_pos - _listPoint[idCurrent].m_pos; - vecB.safeNormalize(); - _listPoint[idCurrent].m_miterAxe = vec2(vecB.y(), vecB.x()); - } else if (_listPoint[idCurrent].m_type == esvg::render::Point::type_stop) { - if (idPevious < 0 ) { - SVG_ERROR("an error occure a previous ID is < 0.... "); - continue; - } - vec2 vecA = _listPoint[idCurrent].m_pos - _listPoint[idPevious].m_pos; - vecA.safeNormalize(); - _listPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x()); - } else { - SVG_TODO("lklklklklkl"); } - } - float lineWidth = 5.0f; - // create segment list: - bool haveStartLine; - vec2 leftPoint; - vec2 rightPoint; - for (int32_t iii=0; - iii < _listPoint.size(); - ++iii) { - switch (_listPoint[iii].m_type) { - case esvg::render::Point::type_single: - // just do nothing .... - SVG_VERBOSE("[" << iii << "] Find Single " << _listPoint[iii].m_pos); - break; - case esvg::render::Point::type_start: - { - SVG_VERBOSE("[" << iii << "] Find Start " << _listPoint[iii].m_pos); - if (haveStartLine == true) { - // close previous : - SVG_WARNING(" find a non close path ..."); + float lineWidth = 5.0f; + // create segment list: + bool haveStartLine; + vec2 leftPoint; + vec2 rightPoint; + for (auto &it : itListPoint) { + switch (it.m_type) { + case esvg::render::Point::type_single: + // just do nothing .... + SVG_VERBOSE("Find Single " << it.m_pos); + break; + case esvg::render::Point::type_start: + { + SVG_VERBOSE("Find Start " << it.m_pos); + if (haveStartLine == true) { + // close previous : + SVG_WARNING(" find a non close path ..."); + 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*lineWidth*0.5f; + rightPoint = it.m_pos + - it.m_miterAxe*lineWidth*0.5f; addSegment(leftPoint, rightPoint); + SVG_VERBOSE(" segment :" << leftPoint << " -> " << rightPoint); } - haveStartLine = true; - // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) - leftPoint = _listPoint[iii].m_pos - + _listPoint[iii].m_miterAxe*lineWidth*0.5f; - rightPoint = _listPoint[iii].m_pos - - _listPoint[iii].m_miterAxe*lineWidth*0.5f; - addSegment(leftPoint, rightPoint); - SVG_VERBOSE(" segment :" << leftPoint << " -> " << rightPoint); - } - break; - case esvg::render::Point::type_stop: - { - SVG_VERBOSE("[" << iii << "] Find Stop " << _listPoint[iii].m_pos); - if (haveStartLine == true) { - SVG_WARNING("find close path without start part ..."); - break; + break; + case esvg::render::Point::type_stop: + { + SVG_VERBOSE("Find Stop " << it.m_pos); + if (haveStartLine == false) { + SVG_WARNING("find close path without start part ..."); + break; + } + haveStartLine = false; + // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) + vec2 left = it.m_pos + + it.m_miterAxe*lineWidth*0.5f; + vec2 right = it.m_pos + - it.m_miterAxe*lineWidth*0.5f; + //Draw from previous point: + addSegment(leftPoint, left); + SVG_VERBOSE(" segment :" << leftPoint << " -> " << left); + addSegment(right, rightPoint); + SVG_VERBOSE(" segment :" << right << " -> " << rightPoint); + leftPoint = left; + rightPoint = right; + // end line ... + addSegment(rightPoint, leftPoint); + SVG_VERBOSE(" segment :" << rightPoint << " -> " << leftPoint); } - haveStartLine = false; - // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) - vec2 left = _listPoint[iii].m_pos - + _listPoint[iii].m_miterAxe*lineWidth*0.5f; - vec2 right = _listPoint[iii].m_pos - - _listPoint[iii].m_miterAxe*lineWidth*0.5f; - //Draw from previous point: - addSegment(leftPoint, left); - SVG_VERBOSE(" segment :" << leftPoint << " -> " << left); - addSegment(right, rightPoint); - SVG_VERBOSE(" segment :" << right << " -> " << rightPoint); - leftPoint = left; - rightPoint = right; - // end line ... - addSegment(rightPoint, leftPoint); - SVG_VERBOSE(" segment :" << rightPoint << " -> " << leftPoint); - } - break; - case esvg::render::Point::type_interpolation: - { - SVG_VERBOSE("[" << iii << "] Find interpolation " << _listPoint[iii].m_pos); - // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) - vec2 left = _listPoint[iii].m_pos - + _listPoint[iii].m_miterAxe*lineWidth*0.5f; - vec2 right = _listPoint[iii].m_pos - - _listPoint[iii].m_miterAxe*lineWidth*0.5f; - //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; - case esvg::render::Point::type_join: - { - SVG_VERBOSE("[" << iii << "] Find Join " << _listPoint[iii].m_pos); - // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) - vec2 left = _listPoint[iii].m_pos - + _listPoint[iii].m_miterAxe*lineWidth*0.5f; - vec2 right = _listPoint[iii].m_pos - - _listPoint[iii].m_miterAxe*lineWidth*0.5f; - //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; + break; + case esvg::render::Point::type_interpolation: + { + SVG_VERBOSE("Find interpolation " << it.m_pos); + // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) + vec2 left = it.m_pos + + it.m_miterAxe*lineWidth*0.5f; + vec2 right = it.m_pos + - it.m_miterAxe*lineWidth*0.5f; + //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; + case esvg::render::Point::type_join: + { + SVG_VERBOSE("Find Join " << it.m_pos); + // TODO : Calculate intersection ... (now we do a simple fast test of path display ...) + vec2 left = it.m_pos + + it.m_miterAxe*lineWidth*0.5f; + vec2 right = it.m_pos + - it.m_miterAxe*lineWidth*0.5f; + //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; + } } } // TODO : Check if it is really usefull ... diff --git a/esvg/render/SegmentList.h b/esvg/render/SegmentList.h index 82e07f5..4fbd008 100644 --- a/esvg/render/SegmentList.h +++ b/esvg/render/SegmentList.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include namespace esvg { namespace render { @@ -22,8 +22,8 @@ namespace esvg { public: SegmentList(); void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1); - void createSegmentList(const std::vector& _listPoint); - void createSegmentListStroke(std::vector& _listPoint); + void createSegmentList(const esvg::render::PointList& _listPoint); + void createSegmentListStroke(esvg::render::PointList& _listPoint); }; } } diff --git a/esvg/render/Weight.cpp b/esvg/render/Weight.cpp index 6d7def9..946a29c 100644 --- a/esvg/render/Weight.cpp +++ b/esvg/render/Weight.cpp @@ -9,6 +9,9 @@ #include #include +#undef __class__ +#define __class__ "render::Weight" + esvg::render::Weight::Weight() { diff --git a/lutin_esvg.py b/lutin_esvg.py index c6259fb..ad95995 100644 --- a/lutin_esvg.py +++ b/lutin_esvg.py @@ -44,6 +44,7 @@ def create(target, module_name): 'esvg/Text.cpp', 'esvg/render/Path.cpp', 'esvg/render/Element.cpp', + 'esvg/render/ElementClose.cpp', 'esvg/render/ElementStop.cpp', 'esvg/render/ElementMoveTo.cpp', 'esvg/render/ElementLineTo.cpp', @@ -55,6 +56,7 @@ def create(target, module_name): 'esvg/render/ElementBezierSmoothCurveTo.cpp', 'esvg/render/ElementElliptic.cpp', 'esvg/render/Point.cpp', + 'esvg/render/PointList.cpp', 'esvg/render/Scanline.cpp', 'esvg/render/Segment.cpp', 'esvg/render/SegmentList.cpp', @@ -77,6 +79,7 @@ def create(target, module_name): 'esvg/Text.h', 'esvg/render/Element.h', 'esvg/render/ElementStop.h', + 'esvg/render/ElementClose.h', 'esvg/render/ElementMoveTo.h', 'esvg/render/ElementLineTo.h', 'esvg/render/ElementLineToH.h', @@ -89,6 +92,7 @@ def create(target, module_name): 'esvg/render/Path.h', 'esvg/render/Scanline.h', 'esvg/render/Point.h', + 'esvg/render/PointList.h', 'esvg/render/Segment.h', 'esvg/render/SegmentList.h', 'esvg/render/Weight.h' diff --git a/test/main.cpp b/test/main.cpp index 292c18d..6a26dc2 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -14,9 +14,32 @@ #undef __class__ #define __class__ "esvg::test" +bool g_visualDebug = false; + + int main(int _argc, const char *_argv[]) { ::testing::InitGoogleTest(&_argc, const_cast(_argv)); etk::init(_argc, _argv); + for (int32_t iii=0; iii<_argc ; ++iii) { + std::string data = _argv[iii]; + #ifdef DEBUG + if (data == "--visual-test") { + TEST_PRINT("visual-test=enable"); + g_visualDebug = true; + } else + #endif + if ( data == "-h" + || data == "--help") { + TEST_PRINT("esvg-test - help : "); + TEST_PRINT(" " << _argv[0] << " [options]"); + #ifdef DEBUG + TEST_PRINT(" --visual-test Enable decoration in logged file in debug mode only"); + #else + TEST_PRINT(" No optiions ..."); + #endif + return -1; + } + } //etk::initDefaultFolder("esvg-test"); return RUN_ALL_TESTS(); } diff --git a/test/main.h b/test/main.h new file mode 100644 index 0000000..184cb4b --- /dev/null +++ b/test/main.h @@ -0,0 +1,17 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2014, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include + +#ifndef __ESVG_TEST_MAIN_H__ +#define __ESVG_TEST_MAIN_H__ + +extern bool g_visualDebug; + + +#endif diff --git a/test/testCircle.cpp b/test/testCircle.cpp index c769a1f..80a2a85 100644 --- a/test/testCircle.cpp +++ b/test/testCircle.cpp @@ -8,6 +8,10 @@ #include #include +#include "main.h" + +#undef __class__ +#define __class__ "TestCircle" TEST(TestCircle, fill) { esvg::Document doc; @@ -15,7 +19,7 @@ TEST(TestCircle, fill) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestCircle_fill.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestCircle_fill.ppm", g_visualDebug); } TEST(TestCircle, stroke) { @@ -24,7 +28,7 @@ TEST(TestCircle, stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestCircle_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestCircle_stroke.ppm", g_visualDebug); } TEST(TestCircle, fill_and_stroke) { @@ -33,5 +37,5 @@ TEST(TestCircle, fill_and_stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestCircle_fill_and_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestCircle_fill_and_stroke.ppm", g_visualDebug); } diff --git a/test/testEllipse.cpp b/test/testEllipse.cpp index 2d1e1c1..d40f50a 100644 --- a/test/testEllipse.cpp +++ b/test/testEllipse.cpp @@ -8,6 +8,10 @@ #include #include +#include "main.h" + +#undef __class__ +#define __class__ "TestEllipse" TEST(TestEllipse, fill) { esvg::Document doc; @@ -15,7 +19,7 @@ TEST(TestEllipse, fill) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill.ppm", g_visualDebug); } TEST(TestEllipse, stroke) { @@ -24,7 +28,7 @@ TEST(TestEllipse, stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestEllipse_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestEllipse_stroke.ppm", g_visualDebug); } TEST(TestEllipse, fill_and_stroke) { @@ -33,5 +37,5 @@ TEST(TestEllipse, fill_and_stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill_and_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill_and_stroke.ppm", g_visualDebug); } \ No newline at end of file diff --git a/test/testLine.cpp b/test/testLine.cpp index b4be139..3c1a810 100644 --- a/test/testLine.cpp +++ b/test/testLine.cpp @@ -8,6 +8,10 @@ #include #include +#include "main.h" + +#undef __class__ +#define __class__ "TestLine" TEST(TestLine, stroke) { esvg::Document doc; @@ -15,5 +19,5 @@ TEST(TestLine, stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestLine_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestLine_stroke.ppm", g_visualDebug); } \ No newline at end of file diff --git a/test/testPath.cpp b/test/testPath.cpp index 57abeae..65f593b 100644 --- a/test/testPath.cpp +++ b/test/testPath.cpp @@ -8,16 +8,10 @@ #include #include -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE v2.0 (see license file) - */ +#include "main.h" -#include -#include +#undef __class__ +#define __class__ "TestPath" TEST(TestPath, fill) { esvg::Document doc; @@ -26,7 +20,7 @@ TEST(TestPath, fill) { " " ""); - doc.generateAnImage(ivec2(100, 100), "TestPath_fill.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestPath_fill.ppm", g_visualDebug); } TEST(TestPath, stroke) { @@ -36,7 +30,7 @@ TEST(TestPath, stroke) { " " ""); - doc.generateAnImage(ivec2(100, 100), "TestPath_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestPath_stroke.ppm", g_visualDebug); } TEST(TestPath, fill_and_stroke) { @@ -46,5 +40,5 @@ TEST(TestPath, fill_and_stroke) { " " ""); - doc.generateAnImage(ivec2(100, 100), "TestPath_fill_and_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestPath_fill_and_stroke.ppm", g_visualDebug); } diff --git a/test/testPolygon.cpp b/test/testPolygon.cpp index 5ac97ec..4e287c3 100644 --- a/test/testPolygon.cpp +++ b/test/testPolygon.cpp @@ -8,6 +8,10 @@ #include #include +#include "main.h" + +#undef __class__ +#define __class__ "TestPolygon" TEST(TestPolygon, fill) { esvg::Document doc; @@ -15,7 +19,7 @@ TEST(TestPolygon, fill) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill.ppm", g_visualDebug); } TEST(TestPolygon, stroke) { @@ -24,7 +28,7 @@ TEST(TestPolygon, stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestPolygon_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestPolygon_stroke.ppm", g_visualDebug); } TEST(TestPolygon, fill_and_stroke) { @@ -33,5 +37,5 @@ TEST(TestPolygon, fill_and_stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill_and_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill_and_stroke.ppm", g_visualDebug); } \ No newline at end of file diff --git a/test/testRectangle.cpp b/test/testRectangle.cpp index d2feee8..88f32ab 100644 --- a/test/testRectangle.cpp +++ b/test/testRectangle.cpp @@ -8,6 +8,10 @@ #include #include +#include "main.h" + +#undef __class__ +#define __class__ "TestRectangle" TEST(TestRectangle, fill) { esvg::Document doc; @@ -15,7 +19,7 @@ TEST(TestRectangle, fill) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill.ppm", g_visualDebug); } TEST(TestRectangle, stroke) { @@ -24,7 +28,7 @@ TEST(TestRectangle, stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestRectangle_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_stroke.ppm", g_visualDebug); } TEST(TestRectangle, fill_and_stroke) { @@ -33,7 +37,7 @@ TEST(TestRectangle, fill_and_stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke.ppm", g_visualDebug); } TEST(TestRectangle, corned_fill) { @@ -42,7 +46,7 @@ TEST(TestRectangle, corned_fill) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill.ppm", g_visualDebug); } TEST(TestRectangle, corned_stroke) { @@ -51,7 +55,7 @@ TEST(TestRectangle, corned_stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_stroke.ppm", g_visualDebug); } TEST(TestRectangle, corned_fill_and_stroke) { @@ -60,5 +64,5 @@ TEST(TestRectangle, corned_fill_and_stroke) { "" " " ""); - doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill_and_stroke.ppm"); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill_and_stroke.ppm", g_visualDebug); }