[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);
virtual ~Base() { };
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 display(int32_t _spacing) { };

View File

@ -8,6 +8,7 @@
#include <esvg/debug.h>
#include <esvg/Path.h>
#include <esvg/render/PointList.h>
#include <esvg/render/Weight.h>
#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() );
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<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 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
}

View File

@ -9,6 +9,9 @@
#include <esvg/debug.h>
#include <esvg/Polyline.h>
#undef __class__
#define __class__ "Polyline"
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.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<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 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
}

View File

@ -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<uint8_t,4>& _colorFill,
const esvg::render::Weight& _weightStroke,
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 (_colorStroke.a() != 0x00) {
// only stroke
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
ivec2 pos(xxx, yyy);
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
#if DEBUG
ivec2 pos(xxx/m_factor, yyy/m_factor);
#else
ivec2 pos(xxx, yyy);
#endif
float valueStroke = _weightStroke.get(pos);
if (valueStroke != 0.0f) {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
m_buffer[(m_size.x()*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[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g());
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b());
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 {
if (_colorStroke.a() == 0x00) {
// only Fill
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
ivec2 pos(xxx, yyy);
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
#if DEBUG
ivec2 pos(xxx/m_factor, yyy/m_factor);
#else
ivec2 pos(xxx, yyy);
#endif
float valueFill = _weightFill.get(pos);
if (valueFill != 0.0f) {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
m_buffer[(m_size.x()*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[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a());
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g());
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b());
m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a());
}
}
}
} else {
// all together
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
ivec2 pos(xxx, yyy);
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
#if DEBUG
ivec2 pos(xxx/m_factor, yyy/m_factor);
#else
ivec2 pos(xxx, yyy);
#endif
float valueFill = _weightFill.get(pos);
float valueStroke = _weightStroke.get(pos);
if (valueStroke != 0.0f) {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
m_buffer[(m_size.x()*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[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g());
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b());
m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
} else {
m_buffer[(m_size.x()*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
m_buffer[(m_size.x()*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[(m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a());
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g());
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b());
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
// 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<sizeX*sizeY; iii++) {
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>
namespace esvg {
class Renderer {
#ifdef DEBUG
private:
bool m_visualDebug;
int32_t m_factor;
#endif
public:
std::vector<uint8_t> 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<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);
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<uint8_t,4>& _colorFill,
const esvg::render::Weight& _weightStroke,
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 ...
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));

View File

@ -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);

View File

@ -8,11 +8,18 @@
#include <esvg/render/Element.h>
#include <esvg/debug.h>
#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;

View File

@ -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 <esvg/render/ElementStop.h>
#include <esvg/render/ElementClose.h>
#include <esvg/render/ElementMoveTo.h>
#include <esvg/render/ElementLineTo.h>
#include <esvg/render/ElementLineToH.h>

View File

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

View File

@ -10,6 +10,8 @@
#include <esvg/debug.h>
#undef __class__
#define __class__ "rerder::ElementBezierSmoothCurveTo"
esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos):
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/debug.h>
#undef __class__
#define __class__ "rerder::ElementCurveTo"
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>
#undef __class__
#define __class__ "rerder::ElementElliptic"
esvg::render::ElementElliptic::ElementElliptic(bool _relative,
const vec2& _radius, // in m_vec1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,9 +10,11 @@
#include <esvg/debug.h>
#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) {
}

View File

@ -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;
};

View File

@ -9,12 +9,19 @@
#include <esvg/render/Path.h>
#include <esvg/render/Element.h>
#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<esvg::render::ElementStop>(_relative));
void esvg::render::Path::stop() {
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) {
@ -109,34 +116,10 @@ void interpolateCubicBezier(std::vector<esvg::render::Point>& _listPoint,
interpolateCubicBezier(_listPoint, _recurtionMax, _threshold, pos1234, pos234, pos34, _pos4, _level+1, _type);
}
void diplayRenderPoints(const std::vector<esvg::render::Point>& 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::Point> 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<esvg::render::Point> out;
esvg::render::PointList out;
std::vector<esvg::render::Point> tmpListPoint;
vec2 lastPosition(0.0f, 0.0f);
int32_t lastPointId = -1;
bool PathStart = false;
@ -145,82 +128,84 @@ std::vector<esvg::render::Point> 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::Point> 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::Point> 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::Point> 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::Point> 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::Point> 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;
}

View File

@ -12,7 +12,7 @@
#include <etk/types.h>
#include <etk/math/Vector2D.h>
#include <esvg/render/Element.h>
#include <esvg/render/Point.h>
#include <esvg/render/PointList.h>
#include <memory>
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<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/debug.h>
#undef __class__
#define __class__ "rerder::Point"
void esvg::render::Point::setEndPath() {
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/debug.h>
#undef __class__
#define __class__ "rerder::Scanline"
esvg::render::Scanline::Scanline(size_t _size) {
float tmp(0);
m_data.resize(_size, tmp);

View File

@ -9,6 +9,8 @@
#include <esvg/render/Segment.h>
#include <esvg/debug.h>
#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

View File

@ -10,6 +10,9 @@
#include <esvg/debug.h>
#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<esvg::render::Point>& _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<esvg::render::Point>& _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 ...

View File

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

View File

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

View File

@ -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'

View File

@ -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<char **>(_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();
}

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 <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestCircle"
TEST(TestCircle, fill) {
esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestCircle, fill) {
"<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' fill='red' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' stroke='green' stroke-width='3' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' stroke='green' stroke-width='3' fill='red' />"
"</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 <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestEllipse"
TEST(TestEllipse, fill) {
esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestEllipse, fill) {
"<svg height='100' width='100'>"
" <ellipse cx='50' cy='50' rx='80' ry='30' fill='red' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <ellipse cx='50' cy='50' rx='80' ry='30' stroke='green' stroke-width='3' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <ellipse cx='50' cy='50' rx='80' ry='30' stroke='green' stroke-width='3' fill='red' />"
"</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 <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestLine"
TEST(TestLine, stroke) {
esvg::Document doc;
@ -15,5 +19,5 @@ TEST(TestLine, stroke) {
"<svg height='100' width='100'>"
" <line x1='10' y1='10' x2='90' y2='90' stroke='green' stroke-width='3' />"
"</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 <esvg/esvg.h>
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include "main.h"
#include <gtest/gtest.h>
#include <esvg/esvg.h>
#undef __class__
#define __class__ "TestPath"
TEST(TestPath, fill) {
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'"
" fill='red' />"
"</svg>");
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) {
" <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' />"
"</svg>");
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) {
" <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' />"
"</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 <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestPolygon"
TEST(TestPolygon, fill) {
esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestPolygon, fill) {
"<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' fill='red' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' stroke='green' stroke-width='3' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' stroke='green' stroke-width='3' fill='red' />"
"</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 <esvg/esvg.h>
#include "main.h"
#undef __class__
#define __class__ "TestRectangle"
TEST(TestRectangle, fill) {
esvg::Document doc;
@ -15,7 +19,7 @@ TEST(TestRectangle, fill) {
"<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' fill='red' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' stroke='green' stroke-width='3' />"
"</svg>");
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) {
"<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' stroke='green' stroke-width='3' fill='red' />"
"</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) {
@ -42,7 +46,7 @@ TEST(TestRectangle, corned_fill) {
"<svg height='100' width='100'>"
" <rect x='12.5' y='12.5' width='75' height='50' rx='20' ry='20' fill='red' />"
"</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) {
@ -51,7 +55,7 @@ TEST(TestRectangle, corned_stroke) {
"<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' />"
"</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) {
@ -60,5 +64,5 @@ TEST(TestRectangle, corned_fill_and_stroke) {
"<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' />"
"</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);
}