[DEV] multiple add:

- add display debug to faster developpement
    - add multiple line path in the pointing list
    - better integration of conficuration of svg parameter
This commit is contained in:
Edouard DUPIN 2015-11-20 21:34:09 +01:00
parent 93d560395f
commit bbfe108c5b
42 changed files with 706 additions and 323 deletions

View File

@ -70,7 +70,7 @@ namespace esvg {
Base(PaintState _parentPaintState); Base(PaintState _parentPaintState);
virtual ~Base() { }; virtual ~Base() { };
virtual bool parse(const std::shared_ptr<exml::Element>& _element, mat2& _parentTrans, vec2& _sizeMax); virtual bool parse(const std::shared_ptr<exml::Element>& _element, mat2& _parentTrans, vec2& _sizeMax);
//specific drawing for AAG librairy ...
virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level=1); virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level=1);
virtual void display(int32_t _spacing) { }; virtual void display(int32_t _spacing) { };

View File

@ -8,6 +8,7 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#include <esvg/Path.h> #include <esvg/Path.h>
#include <esvg/render/PointList.h>
#include <esvg/render/Weight.h> #include <esvg/render/Weight.h>
#undef __class__ #undef __class__
@ -239,7 +240,7 @@ bool esvg::Path::parse(const std::shared_ptr<exml::Element>& _element, mat2& _pa
SVG_WARNING("the PATH command "<< command << " has not the good number of element = " << listDot.size() ); SVG_WARNING("the PATH command "<< command << " has not the good number of element = " << listDot.size() );
break; break;
} }
m_listElement.stop(relative); m_listElement.close(relative);
break; break;
default: default:
SVG_ERROR ("Unknow error : \"" << command << "\""); 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) { void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level) {
SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Path"); SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Path");
int32_t recurtionMax = 10;
float threshold = 0.25f;
mat2 mtx = m_transformMatrix; mat2 mtx = m_transformMatrix;
mtx *= _basicTrans; mtx *= _basicTrans;
std::vector<esvg::render::Point> 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 tmpFill;
esvg::render::Weight tmpStroke; esvg::render::Weight tmpStroke;
// Check if we need to display background // Check if we need to display background
int32_t nbSubScanLine = 8;
if (m_paint.fill.a() != 0x00) { if (m_paint.fill.a() != 0x00) {
esvg::render::SegmentList listSegment; listSegmentFill.createSegmentList(listPoints);
listSegment.createSegmentList(listPoints);
// 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
tmpFill.generate(ivec2(128,128), nbSubScanLine, listSegment); tmpFill.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentFill);
} }
// 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) {
esvg::render::SegmentList listSegment; listSegmentStroke.createSegmentListStroke(listPoints);
listSegment.createSegmentListStroke(listPoints);
// 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(ivec2(128,128), nbSubScanLine, listSegment); tmpStroke.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentStroke);
} }
// add on images: // add on images:
_myRenderer.print(tmpFill, _myRenderer.print(tmpFill,
m_paint.fill, m_paint.fill,
tmpStroke, tmpStroke,
m_paint.stroke); m_paint.stroke);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
#endif
} }

View File

@ -9,6 +9,9 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#include <esvg/Polyline.h> #include <esvg/Polyline.h>
#undef __class__
#define __class__ "Polyline"
esvg::Polyline::Polyline(PaintState _parentPaintState) : esvg::Base(_parentPaintState) { esvg::Polyline::Polyline(PaintState _parentPaintState) : esvg::Base(_parentPaintState) {
} }

View File

@ -67,39 +67,44 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
listElement.lineToH(true, m_size.x()); listElement.lineToH(true, m_size.x());
listElement.lineToV(true, m_size.y()); listElement.lineToV(true, m_size.y());
listElement.lineToH(true, -m_size.x()); listElement.lineToH(true, -m_size.x());
listElement.lineToV(true, -m_size.y()); listElement.close();
listElement.stop();
int32_t recurtionMax = 10;
float threshold = 0.25f;
mat2 mtx = m_transformMatrix; mat2 mtx = m_transformMatrix;
mtx *= _basicTrans; mtx *= _basicTrans;
std::vector<esvg::render::Point> 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 tmpFill;
esvg::render::Weight tmpStroke; esvg::render::Weight tmpStroke;
// Check if we need to display background // Check if we need to display background
int32_t nbSubScanLine = 8;
if (m_paint.fill.a() != 0x00) { if (m_paint.fill.a() != 0x00) {
esvg::render::SegmentList listSegment; listSegmentFill.createSegmentList(listPoints);
listSegment.createSegmentList(listPoints);
// 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
tmpFill.generate(ivec2(128,128), nbSubScanLine, listSegment); tmpFill.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),
listSegmentFill);
} }
// 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) {
esvg::render::SegmentList listSegment; listSegmentStroke.createSegmentListStroke(listPoints);
listSegment.createSegmentListStroke(listPoints);
// 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(ivec2(128,128), nbSubScanLine, listSegment); tmpStroke.generate(_myRenderer.getSize(),
_myRenderer.getNumberSubScanLine(),
listSegmentStroke);
} }
// add on images: // add on images:
_myRenderer.print(tmpFill, _myRenderer.print(tmpFill,
m_paint.fill, m_paint.fill,
tmpStroke, tmpStroke,
m_paint.stroke); m_paint.stroke);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
#endif
} }

View File

@ -15,14 +15,22 @@
#undef __class__ #undef __class__
#define __class__ "Renderer" #define __class__ "Renderer"
esvg::Renderer::Renderer(const ivec2& _size) { esvg::Renderer::Renderer(const ivec2& _size, bool _visualDebug) :
m_size = _size; #ifdef DEBUG
m_buffer.resize(m_size.x() * m_size.y() * DATA_ALLOCATION_ELEMENT, 0); 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() { esvg::Renderer::~Renderer() {
m_buffer.clear(); m_buffer.clear();
m_stride = 0;
m_size = ivec2(0,0); m_size = ivec2(0,0);
} }
@ -30,18 +38,28 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
const etk::Color<uint8_t,4>& _colorFill, const etk::Color<uint8_t,4>& _colorFill,
const esvg::render::Weight& _weightStroke, const esvg::render::Weight& _weightStroke,
const etk::Color<uint8_t,4>& _colorStroke) { const etk::Color<uint8_t,4>& _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 (_colorFill.a() == 0x00) {
if (_colorStroke.a() != 0x00) { if (_colorStroke.a() != 0x00) {
// only stroke // only stroke
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) { for (int32_t yyy=0; yyy<sizeY; ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) { for (int32_t xxx=0; xxx<sizeX; ++xxx) {
ivec2 pos(xxx, yyy); #if DEBUG
ivec2 pos(xxx/m_factor, yyy/m_factor);
#else
ivec2 pos(xxx, yyy);
#endif
float valueStroke = _weightStroke.get(pos); float valueStroke = _weightStroke.get(pos);
if (valueStroke != 0.0f) { if (valueStroke != 0.0f) {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r()); m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
m_buffer[(m_size.x()*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g()); m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g());
m_buffer[(m_size.x()*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b()); m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b());
m_buffer[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a()); m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
} }
} }
} }
@ -49,35 +67,43 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
} else { } else {
if (_colorStroke.a() == 0x00) { if (_colorStroke.a() == 0x00) {
// only Fill // only Fill
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) { for (int32_t yyy=0; yyy<sizeY; ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) { for (int32_t xxx=0; xxx<sizeX; ++xxx) {
ivec2 pos(xxx, yyy); #if DEBUG
ivec2 pos(xxx/m_factor, yyy/m_factor);
#else
ivec2 pos(xxx, yyy);
#endif
float valueFill = _weightFill.get(pos); float valueFill = _weightFill.get(pos);
if (valueFill != 0.0f) { if (valueFill != 0.0f) {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r()); m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
m_buffer[(m_size.x()*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g()); m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g());
m_buffer[(m_size.x()*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b()); m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b());
m_buffer[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a()); m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a());
} }
} }
} }
} else { } else {
// all together // all together
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) { for (int32_t yyy=0; yyy<sizeY; ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) { for (int32_t xxx=0; xxx<sizeX; ++xxx) {
ivec2 pos(xxx, yyy); #if DEBUG
ivec2 pos(xxx/m_factor, yyy/m_factor);
#else
ivec2 pos(xxx, yyy);
#endif
float valueFill = _weightFill.get(pos); float valueFill = _weightFill.get(pos);
float valueStroke = _weightStroke.get(pos); float valueStroke = _weightStroke.get(pos);
if (valueStroke != 0.0f) { if (valueStroke != 0.0f) {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r()); m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
m_buffer[(m_size.x()*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g()); m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g());
m_buffer[(m_size.x()*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b()); m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b());
m_buffer[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a()); m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
} else { } else {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r()); m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
m_buffer[(m_size.x()*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g()); m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g());
m_buffer[(m_size.x()*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b()); m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b());
m_buffer[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a()); m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a());
} }
} }
} }
@ -85,6 +111,50 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
} }
} }
#ifdef DEBUG
void esvg::Renderer::addDebugSegment(const esvg::render::SegmentList& _listSegment) {
if (m_visualDebug == false) {
return;
}
ivec2 dynamicSize = m_size * m_factor;
// for each lines:
for (int32_t yyy=0; yyy<dynamicSize.y(); ++yyy) {
// Reduce the number of lines in the subsampling parsing:
std::vector<esvg::render::Segment> 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<esvg::render::Segment> 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<std::pair<float, float>> 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 // Writing the buffer to a .PPM file, assuming it has
// RGB-structure, one byte per color component // RGB-structure, one byte per color component
//-------------------------------------------------- //--------------------------------------------------
@ -96,7 +166,11 @@ void esvg::Renderer::writePpm(std::string fileName) {
if(fd != nullptr) { if(fd != nullptr) {
int32_t sizeX = m_size.x(); int32_t sizeX = m_size.x();
int32_t sizeY = m_size.y(); 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); fprintf(fd, "P6 %d %d 255 ", sizeX, sizeY);
for (int32_t iii=0 ; iii<sizeX*sizeY; iii++) { for (int32_t iii=0 ; iii<sizeX*sizeY; iii++) {
fwrite(&m_buffer[iii*DATA_ALLOCATION_ELEMENT], 1, 3, fd); fwrite(&m_buffer[iii*DATA_ALLOCATION_ELEMENT], 1, 3, fd);
@ -106,5 +180,49 @@ void esvg::Renderer::writePpm(std::string fileName) {
} }
void esvg::Renderer::setSize(const ivec2& _size) {
m_size = _size;
m_buffer.resize(m_size.x() * m_size.y()
#if DEBUG
* m_factor * m_factor
#endif
* DATA_ALLOCATION_ELEMENT, 0);
}
const ivec2& esvg::Renderer::getSize() const {
return m_size;
}
uint8_t* esvg::Renderer::getDataPointer() {
return &m_buffer[0];
};
uint32_t esvg::Renderer::getDataSize() const {
return m_buffer.size();
};
void esvg::Renderer::setInterpolationRecurtionMax(int32_t _value) {
m_interpolationRecurtionMax = std::avg(1, _value, 200);
}
int32_t esvg::Renderer::getInterpolationRecurtionMax() const {
return m_interpolationRecurtionMax;
}
void esvg::Renderer::setInterpolationThreshold(float _value) {
m_interpolationThreshold = std::avg(0.0f, _value, 20000.0f);
}
float esvg::Renderer::getInterpolationThreshold() const {
return m_interpolationThreshold;
}
void esvg::Renderer::setNumberSubScanLine(int32_t _value) {
m_nbSubScanLine = std::avg(1, _value, 200);
}
int32_t esvg::Renderer::getNumberSubScanLine() const {
return m_nbSubScanLine;
}

View File

@ -15,26 +15,50 @@
#include <esvg/render/Weight.h> #include <esvg/render/Weight.h>
namespace esvg { namespace esvg {
class Renderer { class Renderer {
#ifdef DEBUG
private:
bool m_visualDebug;
int32_t m_factor;
#endif
public: public:
std::vector<uint8_t> m_buffer; Renderer(const ivec2& _size, bool _visualDebug=false);
ivec2 m_size;
int32_t m_stride;
public:
Renderer(const ivec2& _size);
~Renderer(); ~Renderer();
protected:
ivec2 m_size;
public:
void setSize(const ivec2& _size);
const ivec2& getSize() const;
protected:
std::vector<uint8_t> 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); void writePpm(std::string fileName);
uint8_t* getDataPointer() { public:
return &m_buffer[0];
};
uint32_t getDataSize() {
return m_buffer.size();
};
void print(const esvg::render::Weight& _weightFill, void print(const esvg::render::Weight& _weightFill,
const etk::Color<uint8_t,4>& _colorFill, const etk::Color<uint8_t,4>& _colorFill,
const esvg::render::Weight& _weightStroke, const esvg::render::Weight& _weightStroke,
const etk::Color<uint8_t,4>& _colorStroke); const etk::Color<uint8_t,4>& _colorStroke);
#ifdef DEBUG
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
#endif
}; };
}; };

View File

@ -99,7 +99,7 @@ void esvg::Document::generateTestFile()
// FOR TEST only ... // 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(); int32_t sizeX = _size.x();
if (sizeX == 0) { if (sizeX == 0) {
SVG_ERROR("SizeX == 0 ==> set 64"); SVG_ERROR("SizeX == 0 ==> set 64");
@ -114,7 +114,7 @@ void esvg::Document::generateAnImage(const ivec2& _size, const std::string& _fil
delete(m_renderedElement); delete(m_renderedElement);
m_renderedElement = nullptr; 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 ... // create the first element matrix modification ...
mat2 basicTrans; mat2 basicTrans;
//basicTrans *= etk::mat2Translate(vec2(-g_base_dx, -g_base_dy)); //basicTrans *= etk::mat2Translate(vec2(-g_base_dx, -g_base_dy));

View File

@ -68,7 +68,7 @@ namespace esvg {
}; };
void displayDebug(); void displayDebug();
void generateTestFile(); 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(ivec2 _size, draw::Image& _output);
//void generateAnImage(draw::Image& _output); //void generateAnImage(draw::Image& _output);
virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans); virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans);

View File

@ -8,11 +8,18 @@
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::Element"
std::ostream& esvg::operator <<(std::ostream& _os, enum esvg::render::path _obj) { std::ostream& esvg::operator <<(std::ostream& _os, enum esvg::render::path _obj) {
switch (_obj) { switch (_obj) {
case esvg::render::path_stop: case esvg::render::path_stop:
_os << "path_stop"; _os << "path_stop";
break; break;
case esvg::render::path_close:
_os << "path_close";
break;
case esvg::render::path_moveTo: case esvg::render::path_moveTo:
_os << "path_moveTo"; _os << "path_moveTo";
break; break;

View File

@ -16,6 +16,7 @@ namespace esvg {
namespace render { namespace render {
enum path { enum path {
path_stop, path_stop,
path_close,
path_moveTo, path_moveTo,
path_lineTo, path_lineTo,
path_lineToH, path_lineToH,
@ -93,6 +94,7 @@ namespace esvg {
#endif #endif
#include <esvg/render/ElementStop.h> #include <esvg/render/ElementStop.h>
#include <esvg/render/ElementClose.h>
#include <esvg/render/ElementMoveTo.h> #include <esvg/render/ElementMoveTo.h>
#include <esvg/render/ElementLineTo.h> #include <esvg/render/ElementLineTo.h>
#include <esvg/render/ElementLineToH.h> #include <esvg/render/ElementLineToH.h>

View File

@ -9,6 +9,8 @@
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementBezierCurveTo"
esvg::render::ElementBezierCurveTo::ElementBezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos): esvg::render::ElementBezierCurveTo::ElementBezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos):

View File

@ -10,6 +10,8 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementBezierSmoothCurveTo"
esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos): esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_bezierSmoothCurveTo, _relative) { Element(esvg::render::path_bezierSmoothCurveTo, _relative) {

View File

@ -0,0 +1,25 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <esvg/render/Element.h>
#include <esvg/debug.h>
#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 "";
}

View File

@ -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 <etk/types.h>
#include <etk/math/Vector2D.h>
#include <esvg/render/Element.h>
namespace esvg {
namespace render {
class ElementClose : public esvg::render::Element {
public:
ElementClose(bool _relative=false);
public:
virtual std::string display() const;
};
}
}
#endif

View File

@ -9,6 +9,8 @@
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementCurveTo"
esvg::render::ElementCurveTo::ElementCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos): esvg::render::ElementCurveTo::ElementCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos):

View File

@ -10,6 +10,8 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementElliptic"
esvg::render::ElementElliptic::ElementElliptic(bool _relative, esvg::render::ElementElliptic::ElementElliptic(bool _relative,
const vec2& _radius, // in m_vec1 const vec2& _radius, // in m_vec1

View File

@ -10,6 +10,8 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementLineTo"
esvg::render::ElementLineTo::ElementLineTo(bool _relative, const vec2& _pos): esvg::render::ElementLineTo::ElementLineTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_lineTo, _relative) { Element(esvg::render::path_lineTo, _relative) {

View File

@ -9,6 +9,8 @@
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementLineToH"
esvg::render::ElementLineToH::ElementLineToH(bool _relative, float _posX): esvg::render::ElementLineToH::ElementLineToH(bool _relative, float _posX):

View File

@ -9,6 +9,8 @@
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementLineToV"
esvg::render::ElementLineToV::ElementLineToV(bool _relative, float _posY): esvg::render::ElementLineToV::ElementLineToV(bool _relative, float _posY):

View File

@ -9,7 +9,8 @@
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementMoveTo"
esvg::render::ElementMoveTo::ElementMoveTo(bool _relative, const vec2& _pos): esvg::render::ElementMoveTo::ElementMoveTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_moveTo, _relative) { Element(esvg::render::path_moveTo, _relative) {

View File

@ -10,6 +10,8 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementSmoothCurveTo"
esvg::render::ElementSmoothCurveTo::ElementSmoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos): esvg::render::ElementSmoothCurveTo::ElementSmoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos):
Element(esvg::render::path_smoothCurveTo, _relative) { Element(esvg::render::path_smoothCurveTo, _relative) {

View File

@ -10,9 +10,11 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementStop"
esvg::render::ElementStop::ElementStop(bool _relative): esvg::render::ElementStop::ElementStop():
Element(esvg::render::path_stop, _relative) { Element(esvg::render::path_stop) {
} }

View File

@ -17,7 +17,7 @@ namespace esvg {
namespace render { namespace render {
class ElementStop : public esvg::render::Element { class ElementStop : public esvg::render::Element {
public: public:
ElementStop(bool _relative=false); ElementStop();
public: public:
virtual std::string display() const; virtual std::string display() const;
}; };

View File

@ -9,12 +9,19 @@
#include <esvg/render/Path.h> #include <esvg/render/Path.h>
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#undef __class__
#define __class__ "rerder::Path"
void esvg::render::Path::clear() { void esvg::render::Path::clear() {
m_listElement.clear(); m_listElement.clear();
} }
void esvg::render::Path::stop(bool _relative) { void esvg::render::Path::stop() {
m_listElement.push_back(std::make_shared<esvg::render::ElementStop>(_relative)); m_listElement.push_back(std::make_shared<esvg::render::ElementStop>());
}
void esvg::render::Path::close(bool _relative) {
m_listElement.push_back(std::make_shared<esvg::render::ElementClose>(_relative));
} }
void esvg::render::Path::moveTo(bool _relative, const vec2& _pos) { void esvg::render::Path::moveTo(bool _relative, const vec2& _pos) {
@ -109,34 +116,10 @@ void interpolateCubicBezier(std::vector<esvg::render::Point>& _listPoint,
interpolateCubicBezier(_listPoint, _recurtionMax, _threshold, pos1234, pos234, pos34, _pos4, _level+1, _type); interpolateCubicBezier(_listPoint, _recurtionMax, _threshold, pos1234, pos234, pos34, _pos4, _level+1, _type);
} }
void diplayRenderPoints(const std::vector<esvg::render::Point>& listPoints) { esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, int32_t _recurtionMax, float _threshold) {
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::Point> esvg::render::Path::generateListPoints(int32_t _level, int32_t _recurtionMax, float _threshold) {
SVG_VERBOSE(spacingDist(_level) << "Generate List Points ... from a path"); SVG_VERBOSE(spacingDist(_level) << "Generate List Points ... from a path");
std::vector<esvg::render::Point> out; esvg::render::PointList out;
std::vector<esvg::render::Point> tmpListPoint;
vec2 lastPosition(0.0f, 0.0f); vec2 lastPosition(0.0f, 0.0f);
int32_t lastPointId = -1; int32_t lastPointId = -1;
bool PathStart = false; bool PathStart = false;
@ -145,82 +128,84 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
if (it == nullptr) { if (it == nullptr) {
continue; continue;
} }
SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it);
switch (it->getType()) { switch (it->getType()) {
case esvg::render::path_stop: case esvg::render::path_stop:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it); if (tmpListPoint.size() != 0) {
// TODO : Check if the z value mean that the path will cycle ... if (tmpListPoint.size() == 0) {
if (out.size() != 0) {
if (PathStart == false) {
SVG_WARNING(spacingDist(_level+1) << " Request path stop of not starting path ..."); SVG_WARNING(spacingDist(_level+1) << " Request path stop of not starting path ...");
} else { } else {
out.back().setEndPath(); tmpListPoint.back().setEndPath();
PathStart = false; 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 ... // nothing alse to do ...
break; break;
case esvg::render::path_moveTo: case esvg::render::path_moveTo:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it);
// stop last path // stop last path
if (out.size() != 0) { if (tmpListPoint.size() != 0) {
if (PathStart == true) { tmpListPoint.back().setEndPath();
out.back().setEndPath(); out.addList(tmpListPoint);
PathStart = false; tmpListPoint.clear();
}
} }
PathStart = true;
// create a new one // create a new one
if (it->getRelative() == false) { if (it->getRelative() == false) {
lastPosition = vec2(0.0f, 0.0f); lastPosition = vec2(0.0f, 0.0f);
} }
lastPosition += it->getPos(); 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; break;
case esvg::render::path_lineTo: 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 no previous point, we need to create the last point has start ...
if (PathStart == false) { if (tmpListPoint.size() == 0) {
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
PathStart = true;
} }
if (it->getRelative() == false) { if (it->getRelative() == false) {
lastPosition = vec2(0.0f, 0.0f); lastPosition = vec2(0.0f, 0.0f);
} }
lastPosition += it->getPos(); 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; break;
case esvg::render::path_lineToH: 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 no previous point, we need to create the last point has start ...
if (PathStart == false) { if (tmpListPoint.size() == 0) {
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
PathStart = true;
} }
if (it->getRelative() == false) { if (it->getRelative() == false) {
lastPosition = vec2(0.0f, 0.0f); lastPosition = vec2(0.0f, 0.0f);
} }
lastPosition += it->getPos(); 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; break;
case esvg::render::path_lineToV: 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 no previous point, we need to create the last point has start ...
if (PathStart == false) { if (tmpListPoint.size() == 0) {
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start)); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
PathStart = true;
} }
if (it->getRelative() == false) { if (it->getRelative() == false) {
lastPosition = vec2(0.0f, 0.0f); lastPosition = vec2(0.0f, 0.0f);
} }
lastPosition += it->getPos(); 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; break;
case esvg::render::path_curveTo: 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 no previous point, we need to create the last point has start ...
if (PathStart == false) { if (tmpListPoint.size() == 0) {
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join)); tmpListPoint.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join));
PathStart = true;
} }
{ {
vec2 lastPosStore(lastPosition); vec2 lastPosStore(lastPosition);
@ -230,7 +215,7 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
vec2 pos1 = lastPosition + it->getPos1();; vec2 pos1 = lastPosition + it->getPos1();;
vec2 pos2 = lastPosition + it->getPos2();; vec2 pos2 = lastPosition + it->getPos2();;
vec2 pos = lastPosition + it->getPos();; vec2 pos = lastPosition + it->getPos();;
interpolateCubicBezier(out, interpolateCubicBezier(tmpListPoint,
_recurtionMax, _recurtionMax,
_threshold, _threshold,
lastPosStore, lastPosStore,
@ -243,7 +228,6 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
} }
break; break;
case esvg::render::path_smoothCurveTo: case esvg::render::path_smoothCurveTo:
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
/* /*
path.curve4SmoothTo(it->getRelative(), path.curve4SmoothTo(it->getRelative(),
vec2(it->m_element[0], vec2(it->m_element[0],
@ -253,7 +237,6 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
*/ */
break; break;
case esvg::render::path_bezierCurveTo: case esvg::render::path_bezierCurveTo:
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
/* /*
path.curve3To(it->getRelative(), path.curve3To(it->getRelative(),
vec2(it->m_element[0], vec2(it->m_element[0],
@ -263,7 +246,6 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
*/ */
break; break;
case esvg::render::path_bezierSmoothCurveTo: case esvg::render::path_bezierSmoothCurveTo:
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
/* /*
path.curve3SmoothTo(it->getRelative(), path.curve3SmoothTo(it->getRelative(),
vec2(it->m_element[0], vec2(it->m_element[0],
@ -282,13 +264,17 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
it->m_element[5], it->m_element[5],
it->m_element[6] ); it->m_element[6] );
*/ */
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
break; break;
default: default:
SVG_ERROR(spacingDist(_level+1) << " Unknow PATH commant (internal error)"); SVG_ERROR(spacingDist(_level+1) << " Unknow PATH commant (internal error)");
break; break;
} }
} }
diplayRenderPoints(out); if (tmpListPoint.size() != 0) {
SVG_WARNING("TODO ... check this ...");
out.addList(tmpListPoint);
tmpListPoint.clear();
}
out.display();
return out; return out;
} }

View File

@ -12,7 +12,7 @@
#include <etk/types.h> #include <etk/types.h>
#include <etk/math/Vector2D.h> #include <etk/math/Vector2D.h>
#include <esvg/render/Element.h> #include <esvg/render/Element.h>
#include <esvg/render/Point.h> #include <esvg/render/PointList.h>
#include <memory> #include <memory>
namespace esvg { namespace esvg {
@ -29,7 +29,8 @@ namespace esvg {
} }
void clear(); void clear();
void stop(bool _relative=false); void stop();
void close(bool _relative=false);
void moveTo(bool _relative, const vec2& _pos); void moveTo(bool _relative, const vec2& _pos);
void lineTo(bool _relative, const vec2& _pos); void lineTo(bool _relative, const vec2& _pos);
void lineToH(bool _relative, float _posX); void lineToH(bool _relative, float _posX);
@ -45,7 +46,7 @@ namespace esvg {
bool _sweepFlag, bool _sweepFlag,
const vec2& _pos); const vec2& _pos);
void display(int32_t _spacing); void display(int32_t _spacing);
std::vector<esvg::render::Point> 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);
}; };
} }
} }

View File

@ -9,6 +9,8 @@
#include <esvg/render/Point.h> #include <esvg/render/Point.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::Point"
void esvg::render::Point::setEndPath() { void esvg::render::Point::setEndPath() {
if (m_type == esvg::render::Point::type_interpolation) { if (m_type == esvg::render::Point::type_interpolation) {

48
esvg/render/PointList.cpp Normal file
View File

@ -0,0 +1,48 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <esvg/debug.h>
#include <esvg/render/PointList.h>
esvg::render::PointList::PointList() {
// nothing to do ...
}
void esvg::render::PointList::addList(std::vector<esvg::render::Point>& _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;
}
}
}
}

31
esvg/render/PointList.h Normal file
View File

@ -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 <etk/types.h>
#include <etk/math/Vector2D.h>
#include <esvg/render/Element.h>
#include <esvg/render/Point.h>
namespace esvg {
namespace render {
class PointList {
public:
std::vector<std::vector<esvg::render::Point>> m_data;
public:
PointList();
void addList(std::vector<esvg::render::Point>& _list);
void display();
};
}
}
#endif

View File

@ -9,6 +9,9 @@
#include <esvg/render/Scanline.h> #include <esvg/render/Scanline.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::Scanline"
esvg::render::Scanline::Scanline(size_t _size) { esvg::render::Scanline::Scanline(size_t _size) {
float tmp(0); float tmp(0);
m_data.resize(_size, tmp); m_data.resize(_size, tmp);

View File

@ -9,6 +9,8 @@
#include <esvg/render/Segment.h> #include <esvg/render/Segment.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::Segment"
esvg::render::Segment::Segment(const vec2& _p0, const vec2& _p1) { 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 // segment register all time the lower at P0n then we need to register the sens of the path

View File

@ -10,6 +10,9 @@
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::SegmentList"
bool sortSegmentFunction(const esvg::render::Segment& _e1, const esvg::render::Segment& _e2) { bool sortSegmentFunction(const esvg::render::Segment& _e1, const esvg::render::Segment& _e2) {
return _e1.p0.y() < _e2.p0.y(); 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)); m_data.push_back(Segment(_pos0.m_pos, _pos1.m_pos));
} }
void esvg::render::SegmentList::createSegmentList(const std::vector<esvg::render::Point>& _listPoint) { void esvg::render::SegmentList::createSegmentList(const esvg::render::PointList& _listPoint) {
// Build Segments for (auto &it : _listPoint.m_data) {
for (int32_t iii=0, jjj=_listPoint.size()-1; // Build Segments
iii < _listPoint.size(); for (int32_t iii=0, jjj=it.size()-1;
jjj = iii++) { iii < it.size();
addSegment(_listPoint[jjj], _listPoint[iii]); jjj = iii++) {
addSegment(it[jjj], it[iii]);
}
} }
// TODO : Check if it is really usefull ... // TODO : Check if it is really usefull ...
std::sort(m_data.begin(), m_data.end(), sortSegmentFunction); std::sort(m_data.begin(), m_data.end(), sortSegmentFunction);
} }
void esvg::render::SegmentList::createSegmentListStroke(std::vector<esvg::render::Point>& _listPoint) { void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& _listPoint) {
// generate for every point all the orthogonal elements for (auto &itListPoint : _listPoint.m_data) {
// normal edge * end path // generate for every point all the orthogonal elements
// * | * * * * * * * * * * * * * * // normal edge * end path
// * |<--*----this | * // * | * * * * * * * * * * * * * *
// * | * this -->| * // * |<--*----this | *
// * * * | * // * | * this -->| *
// * . | . * . . . . . . . . * * // * * * | *
// * . | . * | * // * . | . * . . . . . . . . * *
// * A . | . B * | * // * . | . * | *
// . * . | * // * A . | . B * | *
// . * * . * * * * * * * * * * * * * // . * . | *
// * * // . * * . * * * * * * * * * * * * *
// * * // * *
// TODO : Start and stop of the path ... // * *
for (int32_t idPevious=-1, idCurrent=0, idNext=1; // TODO : Start and stop of the path ...
idCurrent < _listPoint.size(); for (int32_t idPevious=itListPoint.size()-1, idCurrent=0, idNext=1;
idPevious++, idCurrent++, idNext++) { idCurrent < itListPoint.size();
if ( _listPoint[idCurrent].m_type == esvg::render::Point::type_join idPevious = idCurrent++, idNext++) {
|| _listPoint[idCurrent].m_type == esvg::render::Point::type_interpolation) { if (idNext == itListPoint.size()) {
if (idPevious < 0 ) { idNext = 0;
SVG_ERROR("an error occure a previous ID is < 0.... ");
continue;
} }
if (idNext >= _listPoint.size()) { if ( itListPoint[idCurrent].m_type == esvg::render::Point::type_join
SVG_ERROR("an error occure a next ID is >= nbPoint len .... "); || itListPoint[idCurrent].m_type == esvg::render::Point::type_interpolation) {
continue; if (idPevious < 0 ) {
} SVG_ERROR("an error occure a previous ID is < 0.... ");
vec2 vecA = _listPoint[idCurrent].m_pos - _listPoint[idPevious].m_pos; continue;
vecA.safeNormalize(); }
vec2 vecB = _listPoint[idNext].m_pos - _listPoint[idCurrent].m_pos; if (idNext >= itListPoint.size()) {
vecB.safeNormalize(); SVG_ERROR("an error occure a next ID is >= nbPoint len .... ");
vec2 vecC = vecA - vecB; continue;
if (vecC == vec2(0,0)) { }
// special case: 1 line ... SVG_DEBUG("JOIN : id : prev/curr/next : " << idPevious << "/" << idCurrent << "/" << idNext);
_listPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x()); 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 { } else {
vecC.safeNormalize(); SVG_TODO("lklklklklkl");
_listPoint[idCurrent].m_miterAxe = vecC;
} }
} 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;
float lineWidth = 5.0f; // create segment list:
// create segment list: bool haveStartLine;
bool haveStartLine; vec2 leftPoint;
vec2 leftPoint; vec2 rightPoint;
vec2 rightPoint; for (auto &it : itListPoint) {
for (int32_t iii=0; switch (it.m_type) {
iii < _listPoint.size(); case esvg::render::Point::type_single:
++iii) { // just do nothing ....
switch (_listPoint[iii].m_type) { SVG_VERBOSE("Find Single " << it.m_pos);
case esvg::render::Point::type_single: break;
// just do nothing .... case esvg::render::Point::type_start:
SVG_VERBOSE("[" << iii << "] Find Single " << _listPoint[iii].m_pos); {
break; SVG_VERBOSE("Find Start " << it.m_pos);
case esvg::render::Point::type_start: if (haveStartLine == true) {
{ // close previous :
SVG_VERBOSE("[" << iii << "] Find Start " << _listPoint[iii].m_pos); SVG_WARNING(" find a non close path ...");
if (haveStartLine == true) { addSegment(leftPoint, rightPoint);
// close previous : }
SVG_WARNING(" find a non close path ..."); 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); addSegment(leftPoint, rightPoint);
SVG_VERBOSE(" segment :" << leftPoint << " -> " << rightPoint);
} }
haveStartLine = true; break;
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...) case esvg::render::Point::type_stop:
leftPoint = _listPoint[iii].m_pos {
+ _listPoint[iii].m_miterAxe*lineWidth*0.5f; SVG_VERBOSE("Find Stop " << it.m_pos);
rightPoint = _listPoint[iii].m_pos if (haveStartLine == false) {
- _listPoint[iii].m_miterAxe*lineWidth*0.5f; SVG_WARNING("find close path without start part ...");
addSegment(leftPoint, rightPoint); break;
SVG_VERBOSE(" segment :" << leftPoint << " -> " << rightPoint); }
} haveStartLine = false;
break; // TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
case esvg::render::Point::type_stop: vec2 left = it.m_pos
{ + it.m_miterAxe*lineWidth*0.5f;
SVG_VERBOSE("[" << iii << "] Find Stop " << _listPoint[iii].m_pos); vec2 right = it.m_pos
if (haveStartLine == true) { - it.m_miterAxe*lineWidth*0.5f;
SVG_WARNING("find close path without start part ..."); //Draw from previous point:
break; 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; break;
// TODO : Calculate intersection ... (now we do a simple fast test of path display ...) case esvg::render::Point::type_interpolation:
vec2 left = _listPoint[iii].m_pos {
+ _listPoint[iii].m_miterAxe*lineWidth*0.5f; SVG_VERBOSE("Find interpolation " << it.m_pos);
vec2 right = _listPoint[iii].m_pos // TODO : Calculate intersection ... (now we do a simple fast test of path display ...)
- _listPoint[iii].m_miterAxe*lineWidth*0.5f; vec2 left = it.m_pos
//Draw from previous point: + it.m_miterAxe*lineWidth*0.5f;
addSegment(leftPoint, left); vec2 right = it.m_pos
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left); - it.m_miterAxe*lineWidth*0.5f;
addSegment(right, rightPoint); //Draw from previous point:
SVG_VERBOSE(" segment :" << right << " -> " << rightPoint); addSegment(leftPoint, left);
leftPoint = left; SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
rightPoint = right; addSegment(right, rightPoint);
// end line ... SVG_VERBOSE(" segment :" << right << " -> " << rightPoint);
addSegment(rightPoint, leftPoint); leftPoint = left;
SVG_VERBOSE(" segment :" << rightPoint << " -> " << leftPoint); rightPoint = right;
} }
break; break;
case esvg::render::Point::type_interpolation: case esvg::render::Point::type_join:
{ {
SVG_VERBOSE("[" << iii << "] Find interpolation " << _listPoint[iii].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 ...)
vec2 left = _listPoint[iii].m_pos vec2 left = it.m_pos
+ _listPoint[iii].m_miterAxe*lineWidth*0.5f; + it.m_miterAxe*lineWidth*0.5f;
vec2 right = _listPoint[iii].m_pos vec2 right = it.m_pos
- _listPoint[iii].m_miterAxe*lineWidth*0.5f; - it.m_miterAxe*lineWidth*0.5f;
//Draw from previous point: //Draw from previous point:
addSegment(leftPoint, left); addSegment(leftPoint, left);
SVG_VERBOSE(" segment :" << leftPoint << " -> " << left); SVG_VERBOSE(" segment :" << leftPoint << " -> " << left);
addSegment(right, rightPoint); addSegment(right, rightPoint);
SVG_VERBOSE(" segment :" << right << " -> " << rightPoint); SVG_VERBOSE(" segment :" << right << " -> " << rightPoint);
leftPoint = left; leftPoint = left;
rightPoint = right; rightPoint = right;
} }
break; 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;
} }
} }
// TODO : Check if it is really usefull ... // TODO : Check if it is really usefull ...

View File

@ -12,7 +12,7 @@
#include <etk/types.h> #include <etk/types.h>
#include <etk/math/Vector2D.h> #include <etk/math/Vector2D.h>
#include <esvg/render/Segment.h> #include <esvg/render/Segment.h>
#include <esvg/render/Point.h> #include <esvg/render/PointList.h>
namespace esvg { namespace esvg {
namespace render { namespace render {
@ -22,8 +22,8 @@ namespace esvg {
public: public:
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 std::vector<esvg::render::Point>& _listPoint); void createSegmentList(const esvg::render::PointList& _listPoint);
void createSegmentListStroke(std::vector<esvg::render::Point>& _listPoint); void createSegmentListStroke(esvg::render::PointList& _listPoint);
}; };
} }
} }

View File

@ -9,6 +9,9 @@
#include <esvg/render/Weight.h> #include <esvg/render/Weight.h>
#include <esvg/debug.h> #include <esvg/debug.h>
#undef __class__
#define __class__ "render::Weight"
esvg::render::Weight::Weight() { esvg::render::Weight::Weight() {

View File

@ -44,6 +44,7 @@ def create(target, module_name):
'esvg/Text.cpp', 'esvg/Text.cpp',
'esvg/render/Path.cpp', 'esvg/render/Path.cpp',
'esvg/render/Element.cpp', 'esvg/render/Element.cpp',
'esvg/render/ElementClose.cpp',
'esvg/render/ElementStop.cpp', 'esvg/render/ElementStop.cpp',
'esvg/render/ElementMoveTo.cpp', 'esvg/render/ElementMoveTo.cpp',
'esvg/render/ElementLineTo.cpp', 'esvg/render/ElementLineTo.cpp',
@ -55,6 +56,7 @@ def create(target, module_name):
'esvg/render/ElementBezierSmoothCurveTo.cpp', 'esvg/render/ElementBezierSmoothCurveTo.cpp',
'esvg/render/ElementElliptic.cpp', 'esvg/render/ElementElliptic.cpp',
'esvg/render/Point.cpp', 'esvg/render/Point.cpp',
'esvg/render/PointList.cpp',
'esvg/render/Scanline.cpp', 'esvg/render/Scanline.cpp',
'esvg/render/Segment.cpp', 'esvg/render/Segment.cpp',
'esvg/render/SegmentList.cpp', 'esvg/render/SegmentList.cpp',
@ -77,6 +79,7 @@ def create(target, module_name):
'esvg/Text.h', 'esvg/Text.h',
'esvg/render/Element.h', 'esvg/render/Element.h',
'esvg/render/ElementStop.h', 'esvg/render/ElementStop.h',
'esvg/render/ElementClose.h',
'esvg/render/ElementMoveTo.h', 'esvg/render/ElementMoveTo.h',
'esvg/render/ElementLineTo.h', 'esvg/render/ElementLineTo.h',
'esvg/render/ElementLineToH.h', 'esvg/render/ElementLineToH.h',
@ -89,6 +92,7 @@ def create(target, module_name):
'esvg/render/Path.h', 'esvg/render/Path.h',
'esvg/render/Scanline.h', 'esvg/render/Scanline.h',
'esvg/render/Point.h', 'esvg/render/Point.h',
'esvg/render/PointList.h',
'esvg/render/Segment.h', 'esvg/render/Segment.h',
'esvg/render/SegmentList.h', 'esvg/render/SegmentList.h',
'esvg/render/Weight.h' 'esvg/render/Weight.h'

View File

@ -14,9 +14,32 @@
#undef __class__ #undef __class__
#define __class__ "esvg::test" #define __class__ "esvg::test"
bool g_visualDebug = false;
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
::testing::InitGoogleTest(&_argc, const_cast<char **>(_argv)); ::testing::InitGoogleTest(&_argc, const_cast<char **>(_argv));
etk::init(_argc, _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"); //etk::initDefaultFolder("esvg-test");
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

17
test/main.h Normal file
View File

@ -0,0 +1,17 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#ifndef __ESVG_TEST_MAIN_H__
#define __ESVG_TEST_MAIN_H__
extern bool g_visualDebug;
#endif

View File

@ -8,6 +8,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <esvg/esvg.h> #include <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestCircle"
TEST(TestCircle, fill) { TEST(TestCircle, fill) {
esvg::Document doc; esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestCircle, fill) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' fill='red' />" " <circle cx='50' cy='50' r='40' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestCircle_fill.ppm"); doc.generateAnImage(ivec2(100, 100), "TestCircle_fill.ppm", g_visualDebug);
} }
TEST(TestCircle, stroke) { TEST(TestCircle, stroke) {
@ -24,7 +28,7 @@ TEST(TestCircle, stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' stroke='green' stroke-width='3' />" " <circle cx='50' cy='50' r='40' stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestCircle_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestCircle_stroke.ppm", g_visualDebug);
} }
TEST(TestCircle, fill_and_stroke) { TEST(TestCircle, fill_and_stroke) {
@ -33,5 +37,5 @@ TEST(TestCircle, fill_and_stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' stroke='green' stroke-width='3' fill='red' />" " <circle cx='50' cy='50' r='40' stroke='green' stroke-width='3' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestCircle_fill_and_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestCircle_fill_and_stroke.ppm", g_visualDebug);
} }

View File

@ -8,6 +8,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <esvg/esvg.h> #include <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestEllipse"
TEST(TestEllipse, fill) { TEST(TestEllipse, fill) {
esvg::Document doc; esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestEllipse, fill) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <ellipse cx='50' cy='50' rx='80' ry='30' fill='red' />" " <ellipse cx='50' cy='50' rx='80' ry='30' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill.ppm"); doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill.ppm", g_visualDebug);
} }
TEST(TestEllipse, stroke) { TEST(TestEllipse, stroke) {
@ -24,7 +28,7 @@ TEST(TestEllipse, stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <ellipse cx='50' cy='50' rx='80' ry='30' stroke='green' stroke-width='3' />" " <ellipse cx='50' cy='50' rx='80' ry='30' stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestEllipse_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestEllipse_stroke.ppm", g_visualDebug);
} }
TEST(TestEllipse, fill_and_stroke) { TEST(TestEllipse, fill_and_stroke) {
@ -33,5 +37,5 @@ TEST(TestEllipse, fill_and_stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <ellipse cx='50' cy='50' rx='80' ry='30' stroke='green' stroke-width='3' fill='red' />" " <ellipse cx='50' cy='50' rx='80' ry='30' stroke='green' stroke-width='3' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill_and_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestEllipse_fill_and_stroke.ppm", g_visualDebug);
} }

View File

@ -8,6 +8,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <esvg/esvg.h> #include <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestLine"
TEST(TestLine, stroke) { TEST(TestLine, stroke) {
esvg::Document doc; esvg::Document doc;
@ -15,5 +19,5 @@ TEST(TestLine, stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <line x1='10' y1='10' x2='90' y2='90' stroke='green' stroke-width='3' />" " <line x1='10' y1='10' x2='90' y2='90' stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestLine_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestLine_stroke.ppm", g_visualDebug);
} }

View File

@ -8,16 +8,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <esvg/esvg.h> #include <esvg/esvg.h>
/** #include "main.h"
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h> #undef __class__
#include <esvg/esvg.h> #define __class__ "TestPath"
TEST(TestPath, fill) { TEST(TestPath, fill) {
esvg::Document doc; esvg::Document doc;
@ -26,7 +20,7 @@ TEST(TestPath, fill) {
" <path d='m 50,50 c -12.426,0 -22.5,10.072 -22.5,22.5 0,12.426 10.074,22.5 22.5,22.5 12.428,0 22.5,-10.074 22.5,-22.5 0,-12.427 -10.072,-22.5 -22.5,-22.5 z'" " <path d='m 50,50 c -12.426,0 -22.5,10.072 -22.5,22.5 0,12.426 10.074,22.5 22.5,22.5 12.428,0 22.5,-10.074 22.5,-22.5 0,-12.427 -10.072,-22.5 -22.5,-22.5 z'"
" fill='red' />" " fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPath_fill.ppm"); doc.generateAnImage(ivec2(100, 100), "TestPath_fill.ppm", g_visualDebug);
} }
TEST(TestPath, stroke) { TEST(TestPath, stroke) {
@ -36,7 +30,7 @@ TEST(TestPath, stroke) {
" <path d='m 50,50 c -12.426,0 -22.5,10.072 -22.5,22.5 0,12.426 10.074,22.5 22.5,22.5 12.428,0 22.5,-10.074 22.5,-22.5 0,-12.427 -10.072,-22.5 -22.5,-22.5 z'" " <path d='m 50,50 c -12.426,0 -22.5,10.072 -22.5,22.5 0,12.426 10.074,22.5 22.5,22.5 12.428,0 22.5,-10.074 22.5,-22.5 0,-12.427 -10.072,-22.5 -22.5,-22.5 z'"
" stroke='green' stroke-width='3' />" " stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPath_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestPath_stroke.ppm", g_visualDebug);
} }
TEST(TestPath, fill_and_stroke) { TEST(TestPath, fill_and_stroke) {
@ -46,5 +40,5 @@ TEST(TestPath, fill_and_stroke) {
" <path d='m 50,50 c -12.426,0 -22.5,10.072 -22.5,22.5 0,12.426 10.074,22.5 22.5,22.5 12.428,0 22.5,-10.074 22.5,-22.5 0,-12.427 -10.072,-22.5 -22.5,-22.5 z'" " <path d='m 50,50 c -12.426,0 -22.5,10.072 -22.5,22.5 0,12.426 10.074,22.5 22.5,22.5 12.428,0 22.5,-10.074 22.5,-22.5 0,-12.427 -10.072,-22.5 -22.5,-22.5 z'"
" stroke='green' stroke-width='3' fill='red' />" " stroke='green' stroke-width='3' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPath_fill_and_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestPath_fill_and_stroke.ppm", g_visualDebug);
} }

View File

@ -8,6 +8,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <esvg/esvg.h> #include <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestPolygon"
TEST(TestPolygon, fill) { TEST(TestPolygon, fill) {
esvg::Document doc; esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestPolygon, fill) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' fill='red' />" " <polygon points='50,10 90,50 10,80' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill.ppm"); doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill.ppm", g_visualDebug);
} }
TEST(TestPolygon, stroke) { TEST(TestPolygon, stroke) {
@ -24,7 +28,7 @@ TEST(TestPolygon, stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' stroke='green' stroke-width='3' />" " <polygon points='50,10 90,50 10,80' stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPolygon_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestPolygon_stroke.ppm", g_visualDebug);
} }
TEST(TestPolygon, fill_and_stroke) { TEST(TestPolygon, fill_and_stroke) {
@ -33,5 +37,5 @@ TEST(TestPolygon, fill_and_stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' stroke='green' stroke-width='3' fill='red' />" " <polygon points='50,10 90,50 10,80' stroke='green' stroke-width='3' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill_and_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill_and_stroke.ppm", g_visualDebug);
} }

View File

@ -8,6 +8,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <esvg/esvg.h> #include <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestRectangle"
TEST(TestRectangle, fill) { TEST(TestRectangle, fill) {
esvg::Document doc; esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestRectangle, fill) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' fill='red' />" " <rect x='12.5' y='12.5' width='75' height='50' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill.ppm"); doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill.ppm", g_visualDebug);
} }
TEST(TestRectangle, stroke) { TEST(TestRectangle, stroke) {
@ -24,7 +28,7 @@ TEST(TestRectangle, stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' stroke='green' stroke-width='3' />" " <rect x='12.5' y='12.5' width='75' height='50' stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestRectangle_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestRectangle_stroke.ppm", g_visualDebug);
} }
TEST(TestRectangle, fill_and_stroke) { TEST(TestRectangle, fill_and_stroke) {
@ -33,7 +37,7 @@ TEST(TestRectangle, fill_and_stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' stroke='green' stroke-width='3' fill='red' />" " <rect x='12.5' y='12.5' width='75' height='50' stroke='green' stroke-width='3' fill='red' />"
"</svg>"); "</svg>");
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) { TEST(TestRectangle, corned_fill) {
@ -42,7 +46,7 @@ TEST(TestRectangle, corned_fill) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' fill='red' />" " <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill.ppm"); doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill.ppm", g_visualDebug);
} }
TEST(TestRectangle, corned_stroke) { TEST(TestRectangle, corned_stroke) {
@ -51,7 +55,7 @@ TEST(TestRectangle, corned_stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' stroke='green' stroke-width='3' />" " <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' stroke='green' stroke-width='3' />"
"</svg>"); "</svg>");
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) { TEST(TestRectangle, corned_fill_and_stroke) {
@ -60,5 +64,5 @@ TEST(TestRectangle, corned_fill_and_stroke) {
"<svg height='100' width='100'>" "<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' stroke='green' stroke-width='3' fill='red' />" " <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' stroke='green' stroke-width='3' fill='red' />"
"</svg>"); "</svg>");
doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill_and_stroke.ppm"); doc.generateAnImage(ivec2(100, 100), "TestRectangle_corned_fill_and_stroke.ppm", g_visualDebug);
} }