[DEV] add many test and corect some old bugs ...

This commit is contained in:
Edouard DUPIN 2015-11-19 22:26:42 +01:00
parent bed717cae9
commit 93d560395f
40 changed files with 669 additions and 351 deletions

View File

@ -98,7 +98,7 @@ void esvg::Base::parsePosition(const std::shared_ptr<const exml::Element>& _elem
}
content = _element->getAttribute("y");
if (content.size()!=0) {
_pos.setX(parseLength(content));
_pos.setY(parseLength(content));
}
content = _element->getAttribute("width");
if (content.size()!=0) {

View File

@ -215,14 +215,20 @@ bool esvg::Path::parse(const std::shared_ptr<exml::Element>& _element, mat2& _pa
break;
}
for(int32_t iii=0; iii<listDot.size(); iii+=7) {
bool largeArcFlag = true;
bool sweepFlag = true;
if (listDot[iii+3] == 0.0f) {
largeArcFlag = false;
}
if (listDot[iii+4] == 0.0f) {
sweepFlag = false;
}
m_listElement.ellipticTo(relative,
listDot[iii],
listDot[iii+1],
vec2(listDot[iii], listDot[iii+1]),
listDot[iii+2],
listDot[iii+3],
listDot[iii+4],
listDot[iii+5],
listDot[iii+6]);
largeArcFlag,
sweepFlag,
vec2(listDot[iii+5], listDot[iii+6]) );
}
break;
case 'z': // closepath (relative)
@ -251,10 +257,12 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Path");
int32_t recurtionMax = 10;
float threshold = 0.25f;
std::vector<esvg::render::Point> listPoints = m_listElement.generateListPoints(_level, recurtionMax, threshold);
mat2 mtx = m_transformMatrix;
mtx *= _basicTrans;
std::vector<esvg::render::Point> listPoints = m_listElement.generateListPoints(_level, recurtionMax, threshold);
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
// Check if we need to display background
@ -274,23 +282,9 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
tmpStroke.generate(ivec2(128,128), nbSubScanLine, listSegment);
}
// add on images:
for (int32_t yyy=0; yyy<_myRenderer.m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<_myRenderer.m_size.x(); ++xxx) {
ivec2 pos(xxx, yyy);
float value = tmpFill.get(pos);
float valueStroke = tmpStroke.get(pos);
if (valueStroke != 0.0f) {
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 ] = uint8_t(valueStroke*m_paint.stroke.r());
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 + 1] = uint8_t(valueStroke*m_paint.stroke.g());
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 + 2] = uint8_t(valueStroke*m_paint.stroke.b());
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 + 3] = uint8_t(valueStroke*m_paint.stroke.a());
} else {
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 ] = uint8_t(value*m_paint.fill.r());
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 + 1] = uint8_t(value*m_paint.fill.g());
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 + 2] = uint8_t(value*m_paint.fill.b());
_myRenderer.m_buffer[(_myRenderer.m_size.x()*yyy + xxx)*4 + 3] = uint8_t(value*m_paint.fill.a());
}
}
}
_myRenderer.print(tmpFill,
m_paint.fill,
tmpStroke,
m_paint.stroke);
}

View File

@ -8,6 +8,8 @@
#include <esvg/debug.h>
#include <esvg/Rectangle.h>
#include <esvg/render/Path.h>
#include <esvg/render/Weight.h>
#undef __class__
#define __class__ "Rectangle"
@ -27,9 +29,9 @@ bool esvg::Rectangle::parse(const std::shared_ptr<exml::Element>& _element, mat2
if (_element == nullptr) {
return false;
}
m_position.setValue(0,0);
m_size.setValue(0,0);
m_roundedCorner.setValue(0,0);
m_position.setValue(0.0f, 0.0f);
m_size.setValue(0.0f, 0.0f);
m_roundedCorner.setValue(0.0f, 0.0f);
parseTransform(_element);
parsePaintAttr(_element);
@ -57,38 +59,47 @@ void esvg::Rectangle::display(int32_t _spacing) {
}
void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level) {
SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Rectangle");
SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Rectangle : fill=" << m_paint.fill << " stroke=" << m_paint.stroke);
// TODO : rounded corner ...
esvg::render::Path listElement;
listElement.clear();
listElement.moveTo(false, m_position);
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();
#if 0
_myRenderer.m_renderArea->color(agg::rgba8(m_paint.fill.r, m_paint.fill.g, m_paint.fill.b, m_paint.fill.a));
// Creating a rounded rectangle
agg::rounded_rect rect_r(m_position.x(), m_position.y(), m_position.x()+m_size.x(), m_position.y()+m_size.y(), m_roundedCorner.x());
rect_r.radius(m_roundedCorner.x(), m_roundedCorner.y());
rect_r.normalize_radius();
int32_t recurtionMax = 10;
float threshold = 0.25f;
mat2 mtx = m_transformMatrix;
// herited modifications ...
mtx *= _basicTrans;
if (m_paint.fill.a != 0x00) {
agg::conv_transform<agg::rounded_rect, mat2> trans(rect_r, mtx);
// set the filling mode :
_myRenderer.m_rasterizer.filling_rule((m_paint.flagEvenOdd)?agg::fill_even_odd:agg::fill_non_zero);
_myRenderer.m_rasterizer.add_path(trans);
agg::render_scanlines(_myRenderer.m_rasterizer, _myRenderer.m_scanLine, *_myRenderer.m_renderArea);
}
std::vector<esvg::render::Point> listPoints = listElement.generateListPoints(_level, recurtionMax, threshold);
if (m_paint.strokeWidth > 0 && m_paint.stroke.a!=0x00 ) {
_myRenderer.m_renderArea->color(agg::rgba8(m_paint.stroke.r, m_paint.stroke.g, m_paint.stroke.b, m_paint.stroke.a));
// drawing as an outline
agg::conv_stroke<agg::rounded_rect> rect_p(rect_r);
// set the filling mode :
_myRenderer.m_rasterizer.filling_rule(agg::fill_non_zero);
rect_p.width(m_paint.strokeWidth);
agg::conv_transform<agg::conv_stroke<agg::rounded_rect>, mat2> transStroke(rect_p, mtx);
_myRenderer.m_rasterizer.add_path(transStroke);
agg::render_scanlines(_myRenderer.m_rasterizer, _myRenderer.m_scanLine, *_myRenderer.m_renderArea);
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);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpFill.generate(ivec2(128,128), nbSubScanLine, listSegment);
}
#endif
// check if we need to display stroke:
if ( m_paint.strokeWidth > 0
&& m_paint.stroke.a() != 0x00) {
esvg::render::SegmentList listSegment;
listSegment.createSegmentListStroke(listPoints);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
tmpStroke.generate(ivec2(128,128), nbSubScanLine, listSegment);
}
// add on images:
_myRenderer.print(tmpFill,
m_paint.fill,
tmpStroke,
m_paint.stroke);
}

View File

@ -17,130 +17,73 @@
esvg::Renderer::Renderer(const ivec2& _size) {
m_size = _size;
m_stride = DATA_ALLOCATION_ELEMENT;
m_scanline.resize(m_size.x() * m_stride, 0);
m_buffer.resize(m_size.x() * m_size.y() * m_stride, 0);
m_buffer.resize(m_size.x() * m_size.y() * DATA_ALLOCATION_ELEMENT, 0);
}
esvg::Renderer::~Renderer() {
m_buffer.clear();
m_scanline.clear();
m_stride = 0;
m_size = ivec2(0,0);
}
/*
void nsvgRasterize(NSVGrasterizer* rrr, // this
NSVGimage* image, // image definition
float tx, // move x
float ty, // move y
float scale, // scale
unsigned char* dst, //output image data
int w, // output width
int h, // output height
int stride) // pixel stride
{
NSVGshape *shape = NULL;
NSVGedge *eee = NULL;
NSVGcachedPaint cache;
int i;
rrr->bitmap = dst;
rrr->width = w;
rrr->height = h;
rrr->stride = stride;
if (w > rrr->cscanline) {
rrr->cscanline = w;
rrr->scanline = (unsigned char*)realloc(rrr->scanline, w);
if (rrr->scanline == NULL) return;
}
for (i = 0; i < h; i++)
memset(&dst[i*stride], 0, w*4);
for (shape = image->shapes;
shape != NULL;
shape = shape->next) {
if (!(shape->flags & NSVG_FLAGS_VISIBLE))
continue;
// ***********************
// *** render "fill" *****
// ***********************
if (shape->fill.type != NSVG_PAINT_NONE) {
nsvg__resetPool(rrr);
rrr->freelist = NULL;
rrr->nedges = 0;
nsvg__flattenShape(rrr, shape, scale);
// Scale and translate edges
for (i = 0; i < r->nedges; i++) {
eee = &rrr->edges[i];
eee->x0 = tx + eee->x0;
eee->y0 = (ty + eee->y0) * NSVG__SUBSAMPLES;
eee->x1 = tx + eee->x1;
eee->y1 = (ty + eee->y1) * NSVG__SUBSAMPLES;
}
// Rasterize edges
qsort(rrr->edges,
rrr->nedges,
sizeof(NSVGedge),
nsvg__cmpEdge);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
nsvg__initPaint(&cache,
&shape->fill,
shape->opacity);
nsvg__rasterizeSortedEdges(rrr,
tx,
ty,
scale,
&cache,
shape->fillRule);
}
// *************************
// *** render "stroke" *****
// *************************
if ( shape->stroke.type != NSVG_PAINT_NONE
&& (shape->strokeWidth * scale) > 0.01f) {
nsvg__resetPool(r);
rrr->freelist = NULL;
rrr->nedges = 0;
nsvg__flattenShapeStroke(rrr, shape, scale);
// dumpEdges(r, "edge.svg");
// Scale and translate edges
for (i = 0; i < rrr->nedges; i++) {
eee = &rrr->edges[i];
eee->x0 = tx + eee->x0;
eee->y0 = (ty + eee->y0) * NSVG__SUBSAMPLES;
eee->x1 = tx + eee->x1;
eee->y1 = (ty + eee->y1) * NSVG__SUBSAMPLES;
}
// Rasterize edges
qsort(rrr->edges,
rrr->nedges,
sizeof(NSVGedge),
nsvg__cmpEdge);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
nsvg__initPaint(&cache,
&shape->stroke,
shape->opacity);
nsvg__rasterizeSortedEdges(rrr,
tx,
ty,
scale,
&cache,
NSVG_FILLRULE_NONZERO);
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) {
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);
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());
}
}
}
}
} 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);
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());
}
}
}
} 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);
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());
} 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());
}
}
}
}
}
nsvg__unpremultiplyAlpha(dst,
w,
h,
stride);
rrr->bitmap = NULL;
rrr->width = 0;
rrr->height = 0;
rrr->stride = 0;
}
*/
// Writing the buffer to a .PPM file, assuming it has
// RGB-structure, one byte per color component
@ -150,7 +93,7 @@ void esvg::Renderer::writePpm(std::string fileName) {
return;
}
FILE* fd = fopen(fileName.c_str(), "wb");
if(NULL != fd) {
if(fd != nullptr) {
int32_t sizeX = m_size.x();
int32_t sizeY = m_size.y();
SVG_DEBUG("Generate ppm : " << m_size);

View File

@ -12,12 +12,12 @@
#include <etk/types.h>
#include <etk/math/Vector2D.h>
#include <etk/Color.h>
#include <esvg/render/Weight.h>
namespace esvg {
class Renderer {
public:
std::vector<uint8_t> m_scanline;
std::vector<uint8_t> m_buffer;
ivec2 m_size;
int32_t m_stride;
@ -31,6 +31,10 @@ namespace esvg {
uint32_t getDataSize() {
return m_buffer.size();
};
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);
};
};

View File

@ -28,8 +28,8 @@ esvg::Document::Document() :
m_fileName = "";
m_version = "0.0";
m_loadOK = false;
m_paint.fill = etk::color::red;
m_paint.stroke = etk::color::white;
m_paint.fill = etk::color::none;
m_paint.stroke = etk::color::none;
m_paint.strokeWidth = 1.0;
m_paint.viewPort.setValue(255,255);
@ -98,14 +98,14 @@ void esvg::Document::generateTestFile()
}
void esvg::Document::generateAnImage(int32_t _sizeX, int32_t _sizeY) {
int32_t sizeX = _sizeX;
// FOR TEST only ...
void esvg::Document::generateAnImage(const ivec2& _size, const std::string& _fileName) {
int32_t sizeX = _size.x();
if (sizeX == 0) {
SVG_ERROR("SizeX == 0 ==> set 64");
sizeX = 64;
}
int32_t sizeY = _sizeY;
int32_t sizeY = _size.y();
if (sizeY == 0) {
SVG_ERROR("SizeY == 0 ==> set 64");
sizeY = 64;
@ -125,8 +125,7 @@ void esvg::Document::generateAnImage(int32_t _sizeX, int32_t _sizeY) {
//basicTrans *= etk::mat2Translate(vec2(width/3, height/3));
draw(*m_renderedElement, basicTrans);
std::string tmpFileOut = "zzz_out_test.ppm";
m_renderedElement->writePpm(tmpFileOut);
m_renderedElement->writePpm(_fileName);
}
/*
void esvg::Document::generateAnImage(draw::Image& _output) {
@ -165,8 +164,8 @@ void esvg::Document::clear() {
m_fileName = "";
m_version = "0.0";
m_loadOK = true;
m_paint.fill = etk::color::red;
m_paint.stroke = etk::color::white;
m_paint.fill = etk::color::none;
m_paint.stroke = etk::color::none;
m_paint.strokeWidth = 1.0;
m_paint.viewPort.setValue(255,255);

View File

@ -68,7 +68,7 @@ namespace esvg {
};
void displayDebug();
void generateTestFile();
void generateAnImage(int32_t _sizeX, int32_t _sizeY);
void generateAnImage(const ivec2& _size, const std::string& _fileName);
//void generateAnImage(ivec2 _size, draw::Image& _output);
//void generateAnImage(draw::Image& _output);
virtual void draw(esvg::Renderer& _myRenderer, mat2& _basicTrans);

View File

@ -8,5 +8,48 @@
#include <esvg/render/Element.h>
#include <esvg/debug.h>
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_moveTo:
_os << "path_moveTo";
break;
case esvg::render::path_lineTo:
_os << "path_lineTo";
break;
case esvg::render::path_lineToH:
_os << "path_lineToH";
break;
case esvg::render::path_lineToV:
_os << "path_lineToV";
break;
case esvg::render::path_curveTo:
_os << "path_curveTo";
break;
case esvg::render::path_smoothCurveTo:
_os << "path_smoothCurveTo";
break;
case esvg::render::path_bezierCurveTo:
_os << "path_bezierCurveTo";
break;
case esvg::render::path_bezierSmoothCurveTo:
_os << "path_bezierSmoothCurveTo";
break;
case esvg::render::path_elliptic:
_os << "path_elliptic";
break;
default:
_os << "????";
break;
};
return _os;
}
std::ostream& esvg::operator <<(std::ostream& _os, const esvg::render::Element& _obj) {
_os << _obj.getType();
_os << ": rel=" << etk::to_string(_obj.getRelative()) << " ";
_os << _obj.display();
return _os;
}

View File

@ -76,8 +76,18 @@ namespace esvg {
void setPos2(const vec2& _val) {
m_pos2 = _val;
}
public:
virtual std::string display() const = 0;
};
}
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
std::ostream& operator <<(std::ostream& _os, const esvg::render::Element& _obj);
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
std::ostream& operator <<(std::ostream& _os, enum esvg::render::path _obj);
}
#endif

View File

@ -10,3 +10,13 @@
#include <esvg/debug.h>
esvg::render::ElementBezierCurveTo::ElementBezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos):
Element(esvg::render::path_bezierCurveTo, _relative) {
m_pos = _pos;
m_pos1 = _pos1;
}
std::string esvg::render::ElementBezierCurveTo::display() const {
return std::string("pos=") + etk::to_string(m_pos) + " pos1=" + etk::to_string(m_pos1);
}

View File

@ -15,13 +15,11 @@
namespace esvg {
namespace render {
class ElementBezierCurveTo : public Element {
class ElementBezierCurveTo : public esvg::render::Element {
public:
ElementBezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos):
Element(esvg::render::path_bezierCurveTo, _relative) {
m_pos = _pos;
m_pos1 = _pos1;
}
ElementBezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,13 @@
#include <esvg/debug.h>
esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_bezierSmoothCurveTo, _relative) {
m_pos = _pos;
}
std::string esvg::render::ElementBezierSmoothCurveTo::display() const {
return std::string("pos=") + etk::to_string(m_pos);
}

View File

@ -15,12 +15,11 @@
namespace esvg {
namespace render {
class ElementBezierSmoothCurveTo : public Element {
class ElementBezierSmoothCurveTo : public esvg::render::Element {
public:
ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_bezierSmoothCurveTo, _relative) {
m_pos = _pos;
}
ElementBezierSmoothCurveTo(bool _relative, const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,16 @@
#include <esvg/debug.h>
esvg::render::ElementCurveTo::ElementCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos):
Element(esvg::render::path_curveTo, _relative) {
m_pos = _pos;
m_pos1 = _pos1;
m_pos2 = _pos2;
}
std::string esvg::render::ElementCurveTo::display() const {
return std::string("pos=") + etk::to_string(m_pos) + " pos1=" + etk::to_string(m_pos1) + " pos2=" + etk::to_string(m_pos2);
}

View File

@ -15,14 +15,11 @@
namespace esvg {
namespace render {
class ElementCurveTo : public Element {
class ElementCurveTo : public esvg::render::Element {
public:
ElementCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos):
Element(esvg::render::path_curveTo, _relative) {
m_pos = _pos;
m_pos1 = _pos1;
m_pos2 = _pos2;
}
ElementCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,26 @@
#include <esvg/debug.h>
esvg::render::ElementElliptic::ElementElliptic(bool _relative,
const vec2& _radius, // in m_vec1
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
const vec2& _pos):
Element(esvg::render::path_elliptic, _relative) {
m_pos1 = _radius;
m_pos = _pos;
m_angle = _angle;
m_largeArcFlag = _largeArcFlag;
m_sweepFlag = _sweepFlag;
}
std::string esvg::render::ElementElliptic::display() const {
return std::string("pos=") + etk::to_string(m_pos)
+ " radius=" + etk::to_string(m_pos1)
+ " angle=" + etk::to_string(m_angle)
+ " largeArcFlag=" + etk::to_string(m_largeArcFlag)
+ " sweepFlag=" + etk::to_string(m_sweepFlag);
}

View File

@ -15,12 +15,20 @@
namespace esvg {
namespace render {
class ElementElliptic : public Element {
class ElementElliptic : public esvg::render::Element {
private:
float m_angle;
bool m_largeArcFlag;
bool m_sweepFlag;
public:
ElementElliptic(bool _relative, float _val0, float _val1, float _val2, float _val3, float _val4, float _val5, float _val6):
Element(esvg::render::path_elliptic, _relative) {
// TODO ... later ...
}
ElementElliptic(bool _relative,
const vec2& _radius, // in m_pos1
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,13 @@
#include <esvg/debug.h>
esvg::render::ElementLineTo::ElementLineTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_lineTo, _relative) {
m_pos = _pos;
}
std::string esvg::render::ElementLineTo::display() const {
return std::string("pos=") + etk::to_string(m_pos);
}

View File

@ -15,12 +15,11 @@
namespace esvg {
namespace render {
class ElementLineTo : public Element {
class ElementLineTo : public esvg::render::Element {
public:
ElementLineTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_lineTo, _relative) {
m_pos = _pos;
}
ElementLineTo(bool _relative, const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,13 @@
#include <esvg/debug.h>
esvg::render::ElementLineToH::ElementLineToH(bool _relative, float _posX):
Element(esvg::render::path_lineToH, _relative) {
m_pos = vec2(_posX, 0.0f);
}
std::string esvg::render::ElementLineToH::display() const {
return std::string("posX=") + etk::to_string(m_pos.x());
}

View File

@ -15,12 +15,11 @@
namespace esvg {
namespace render {
class ElementLineToH : public Element {
class ElementLineToH : public esvg::render::Element {
public:
ElementLineToH(bool _relative, float _posX):
Element(esvg::render::path_lineToH, _relative) {
m_pos = vec2(_posX, 0.0f);
}
ElementLineToH(bool _relative, float _posX);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,13 @@
#include <esvg/debug.h>
esvg::render::ElementLineToV::ElementLineToV(bool _relative, float _posY):
Element(esvg::render::path_lineToV, _relative) {
m_pos = vec2(0.0f, _posY);
}
std::string esvg::render::ElementLineToV::display() const {
return std::string("posY=") + etk::to_string(m_pos.y());
}

View File

@ -15,12 +15,11 @@
namespace esvg {
namespace render {
class ElementLineToV : public Element {
class ElementLineToV : public esvg::render::Element {
public:
ElementLineToV(bool _relative, float _posY):
Element(esvg::render::path_lineToV, _relative) {
m_pos = vec2(0.0f, _posY);
}
ElementLineToV(bool _relative, float _posY);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,13 @@
#include <esvg/debug.h>
esvg::render::ElementMoveTo::ElementMoveTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_moveTo, _relative) {
m_pos = _pos;
}
std::string esvg::render::ElementMoveTo::display() const {
return std::string("pos=") + etk::to_string(m_pos);
}

View File

@ -15,12 +15,11 @@
namespace esvg {
namespace render {
class ElementMoveTo : public Element {
class ElementMoveTo : public esvg::render::Element {
public:
ElementMoveTo(bool _relative, const vec2& _pos):
Element(esvg::render::path_moveTo, _relative) {
m_pos = _pos;
}
ElementMoveTo(bool _relative, const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,14 @@
#include <esvg/debug.h>
esvg::render::ElementSmoothCurveTo::ElementSmoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos):
Element(esvg::render::path_smoothCurveTo, _relative) {
m_pos = _pos;
m_pos2 = _pos2;
}
std::string esvg::render::ElementSmoothCurveTo::display() const {
return std::string("pos=") + etk::to_string(m_pos) + " pos2=" + etk::to_string(m_pos2);
}

View File

@ -15,13 +15,11 @@
namespace esvg {
namespace render {
class ElementSmoothCurveTo : public Element {
class ElementSmoothCurveTo : public esvg::render::Element {
public:
ElementSmoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos):
Element(esvg::render::path_smoothCurveTo, _relative) {
m_pos = _pos;
m_pos2 = _pos2;
}
ElementSmoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos);
public:
virtual std::string display() const;
};
}
}

View File

@ -10,3 +10,14 @@
#include <esvg/debug.h>
esvg::render::ElementStop::ElementStop(bool _relative):
Element(esvg::render::path_stop, _relative) {
}
std::string esvg::render::ElementStop::display() const {
return "";
}

View File

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

View File

@ -14,43 +14,48 @@ void esvg::render::Path::clear() {
}
void esvg::render::Path::stop(bool _relative) {
m_listElement.push_back(esvg::render::ElementStop(_relative));
m_listElement.push_back(std::make_shared<esvg::render::ElementStop>(_relative));
}
void esvg::render::Path::moveTo(bool _relative, const vec2& _pos) {
m_listElement.push_back(esvg::render::ElementMoveTo(_relative, _pos));
m_listElement.push_back(std::make_shared<esvg::render::ElementMoveTo>(_relative, _pos));
}
void esvg::render::Path::lineTo(bool _relative, const vec2& _pos) {
m_listElement.push_back(esvg::render::ElementLineTo(_relative, _pos));
m_listElement.push_back(std::make_shared<esvg::render::ElementLineTo>(_relative, _pos));
}
void esvg::render::Path::lineToH(bool _relative, float _posX) {
m_listElement.push_back(esvg::render::ElementLineToH(_relative, _posX));
m_listElement.push_back(std::make_shared<esvg::render::ElementLineToH>(_relative, _posX));
}
void esvg::render::Path::lineToV(bool _relative, float _posY) {
m_listElement.push_back(esvg::render::ElementLineToV(_relative, _posY));
m_listElement.push_back(std::make_shared<esvg::render::ElementLineToV>(_relative, _posY));
}
void esvg::render::Path::curveTo(bool _relative, const vec2& _pos1, const vec2& _pos2, const vec2& _pos) {
m_listElement.push_back(esvg::render::ElementCurveTo(_relative, _pos1, _pos2, _pos));
m_listElement.push_back(std::make_shared<esvg::render::ElementCurveTo>(_relative, _pos1, _pos2, _pos));
}
void esvg::render::Path::smoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos) {
m_listElement.push_back(esvg::render::ElementSmoothCurveTo(_relative, _pos2, _pos));
m_listElement.push_back(std::make_shared<esvg::render::ElementSmoothCurveTo>(_relative, _pos2, _pos));
}
void esvg::render::Path::bezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos) {
m_listElement.push_back(esvg::render::ElementBezierCurveTo(_relative, _pos1, _pos));
m_listElement.push_back(std::make_shared<esvg::render::ElementBezierCurveTo>(_relative, _pos1, _pos));
}
void esvg::render::Path::bezierSmoothCurveTo(bool _relative, const vec2& _pos) {
m_listElement.push_back(esvg::render::ElementBezierSmoothCurveTo(_relative, _pos));
m_listElement.push_back(std::make_shared<esvg::render::ElementBezierSmoothCurveTo>(_relative, _pos));
}
void esvg::render::Path::ellipticTo(bool _relative, float _val0, float _val1, float _val2, float _val3, float _val4, float _val5, float _val6) {
m_listElement.push_back(esvg::render::ElementElliptic(_relative, _val0, _val1, _val2, _val3, _val4, _val5, _val6));
void esvg::render::Path::ellipticTo(bool _relative,
const vec2& _radius,
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
const vec2& _pos) {
m_listElement.push_back(std::make_shared<esvg::render::ElementElliptic>(_relative, _radius, _angle, _largeArcFlag, _sweepFlag, _pos));
}
static const char* spacingDist(int32_t _spacing) {
@ -64,42 +69,10 @@ static const char* spacingDist(int32_t _spacing) {
void esvg::render::Path::display(int32_t _spacing) {
SVG_DEBUG(spacingDist(_spacing) << "Path");
for(auto &it : m_listElement) {
switch (it.getType()) {
case esvg::render::path_stop:
SVG_DEBUG(spacingDist(_spacing+4) << "STOP");
break;
case esvg::render::path_moveTo:
SVG_DEBUG(spacingDist(_spacing+4) << "MOVETO " << it.getPos() );
break;
case esvg::render::path_lineTo:
SVG_DEBUG(spacingDist(_spacing+4) << "LINETO " << it.getPos() );
break;
case esvg::render::path_lineToH:
SVG_DEBUG(spacingDist(_spacing+4) << "LINETO_H " << it.getPos().x());
break;
case esvg::render::path_lineToV:
SVG_DEBUG(spacingDist(_spacing+4) << "LINETO_V " << it.getPos().y() );
break;
case esvg::render::path_curveTo:
SVG_DEBUG(spacingDist(_spacing+4) << "CURVETO " << it.getPos2() << " " << it.getPos1() << " " << it.getPos() );
break;
case esvg::render::path_smoothCurveTo:
SVG_DEBUG(spacingDist(_spacing+4) << "SMOOTH_CURVETO " << it.getPos2() << " " << it.getPos() );
break;
case esvg::render::path_bezierCurveTo:
SVG_DEBUG(spacingDist(_spacing+4) << "BEZIER_CURVETO " << it.getPos1() << " " << it.getPos() );
break;
case esvg::render::path_bezierSmoothCurveTo:
SVG_DEBUG(spacingDist(_spacing+4) << "BEZIER_SMOOTH_CURVETO " << it.getPos() );
break;
case esvg::render::path_elliptic:
SVG_DEBUG(spacingDist(_spacing+4) << "ELLIPTIC ???");
// show explanation at : http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
break;
default:
SVG_DEBUG(spacingDist(_spacing+4) << "????" );
break;
if (it == nullptr) {
continue;
}
SVG_DEBUG(spacingDist(_spacing+1) << *it);
}
}
@ -169,9 +142,12 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
bool PathStart = false;
// Foreach element, we move in the path:
for(auto &it : m_listElement) {
switch (it.getType()) {
if (it == nullptr) {
continue;
}
switch (it->getType()) {
case esvg::render::path_stop:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : 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) {
@ -184,7 +160,7 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
// nothing alse to do ...
break;
case esvg::render::path_moveTo:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : esvg::render::path_moveTo");
SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it);
// stop last path
if (out.size() != 0) {
if (PathStart == true) {
@ -194,53 +170,53 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
}
PathStart = true;
// create a new one
if (it.getRelative() == false) {
if (it->getRelative() == false) {
lastPosition = vec2(0.0f, 0.0f);
}
lastPosition += it.getPos();
lastPosition += it->getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
break;
case esvg::render::path_lineTo:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : 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_join));
out.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 += it.getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
lastPosition += it->getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join));
break;
case esvg::render::path_lineToH:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : 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_join));
out.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 += it.getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
lastPosition += it->getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join));
break;
case esvg::render::path_lineToV:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : 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_join));
out.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 += it.getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_start));
lastPosition += it->getPos();
out.push_back(esvg::render::Point(lastPosition, esvg::render::Point::type_join));
break;
case esvg::render::path_curveTo:
SVG_VERBOSE(spacingDist(_level+1) << " Draw : 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));
@ -248,12 +224,12 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
}
{
vec2 lastPosStore(lastPosition);
if (it.getRelative() == false) {
if (it->getRelative() == false) {
lastPosition = vec2(0.0f, 0.0f);
}
vec2 pos1 = lastPosition + it.getPos1();;
vec2 pos2 = lastPosition + it.getPos2();;
vec2 pos = lastPosition + it.getPos();;
vec2 pos1 = lastPosition + it->getPos1();;
vec2 pos2 = lastPosition + it->getPos2();;
vec2 pos = lastPosition + it->getPos();;
interpolateCubicBezier(out,
_recurtionMax,
_threshold,
@ -267,46 +243,46 @@ std::vector<esvg::render::Point> esvg::render::Path::generateListPoints(int32_t
}
break;
case esvg::render::path_smoothCurveTo:
SVG_TODO(spacingDist(_level+1) << " Draw : esvg::render::path_smoothCurveTo");
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
/*
path.curve4SmoothTo(it.getRelative(),
vec2(it.m_element[0],
it.m_element[1]),
vec2(it.m_element[2],
it.m_element[3]) );
path.curve4SmoothTo(it->getRelative(),
vec2(it->m_element[0],
it->m_element[1]),
vec2(it->m_element[2],
it->m_element[3]) );
*/
break;
case esvg::render::path_bezierCurveTo:
SVG_TODO(spacingDist(_level+1) << " Draw : esvg::render::path_bezierCurveTo");
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
/*
path.curve3To(it.getRelative(),
vec2(it.m_element[0],
it.m_element[1]),
vec2(it.m_element[2],
it.m_element[3]) );
path.curve3To(it->getRelative(),
vec2(it->m_element[0],
it->m_element[1]),
vec2(it->m_element[2],
it->m_element[3]) );
*/
break;
case esvg::render::path_bezierSmoothCurveTo:
SVG_TODO(spacingDist(_level+1) << " Draw : esvg::render::path_bezierSmoothCurveTo");
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
/*
path.curve3SmoothTo(it.getRelative(),
vec2(it.m_element[0],
it.m_element[1]) );
path.curve3SmoothTo(it->getRelative(),
vec2(it->m_element[0],
it->m_element[1]) );
*/
break;
case esvg::render::path_elliptic:
/*
SVG_VERBOSE(spacingDist(_level+1) << " Draw : esvg::render::path_elliptic");
path.ellipticTo(it.getRelative(),
it.m_element[0],
it.m_element[1],
it.m_element[2],
it.m_element[3],
it.m_element[4],
it.m_element[5],
it.m_element[6] );
SVG_VERBOSE(spacingDist(_level+1) << " Draw : " << *it);
path.ellipticTo(it->getRelative(),
it->m_element[0],
it->m_element[1],
it->m_element[2],
it->m_element[3],
it->m_element[4],
it->m_element[5],
it->m_element[6] );
*/
SVG_TODO(spacingDist(_level+1) << " Draw : esvg::render::path_elliptic");
SVG_TODO(spacingDist(_level+1) << " Draw : " << *it);
break;
default:
SVG_ERROR(spacingDist(_level+1) << " Unknow PATH commant (internal error)");

View File

@ -13,12 +13,13 @@
#include <etk/math/Vector2D.h>
#include <esvg/render/Element.h>
#include <esvg/render/Point.h>
#include <memory>
namespace esvg {
namespace render {
class Path {
public:
std::vector<esvg::render::Element> m_listElement;
std::vector<std::shared_ptr<esvg::render::Element>> m_listElement;
public:
Path() {
@ -28,7 +29,7 @@ namespace esvg {
}
void clear();
void stop(bool _relative);
void stop(bool _relative=false);
void moveTo(bool _relative, const vec2& _pos);
void lineTo(bool _relative, const vec2& _pos);
void lineToH(bool _relative, float _posX);
@ -37,7 +38,12 @@ namespace esvg {
void smoothCurveTo(bool _relative, const vec2& _pos2, const vec2& _pos);
void bezierCurveTo(bool _relative, const vec2& _pos1, const vec2& _pos);
void bezierSmoothCurveTo(bool _relative, const vec2& _pos);
void ellipticTo(bool _relative, float _val0, float _val1, float _val2, float _val3, float _val4, float _val5, float _val6);
void ellipticTo(bool _relative,
const vec2& _radius,
float _angle,
bool _largeArcFlag,
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);
};

View File

@ -28,8 +28,15 @@ def create(target, module_name):
my_module = module.Module(__file__, module_name, get_type())
my_module.add_src_file([
'test/main.cpp',
'test/testCircle.cpp',
'test/testEllipse.cpp',
'test/testGroup.cpp',
'test/testLine.cpp',
'test/testParsingFile.cpp',
'test/testPath.cpp',
'test/testPolygon.cpp',
'test/testPolyline.cpp',
'test/testRectangle.cpp'
])
my_module.add_module_depend(['esvg', 'gtest', 'test-debug'])
return my_module

37
test/testCircle.cpp Normal file
View File

@ -0,0 +1,37 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <esvg/esvg.h>
TEST(TestCircle, fill) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <circle cx='50' cy='50' r='40' fill='red' />"
"</svg>");
doc.generateAnImage(ivec2(100, 100), "TestCircle_fill.ppm");
}
TEST(TestCircle, stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestCircle, fill_and_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}

37
test/testEllipse.cpp Normal file
View File

@ -0,0 +1,37 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <esvg/esvg.h>
TEST(TestEllipse, fill) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestEllipse, stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestEllipse, fill_and_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}

0
test/testGroup.cpp Normal file
View File

19
test/testLine.cpp Normal file
View File

@ -0,0 +1,19 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <esvg/esvg.h>
TEST(TestLine, stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}

View File

@ -6,27 +6,45 @@
* @license APACHE v2.0 (see license file)
*/
#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 <gtest/gtest.h>
#include <esvg/esvg.h>
TEST(TestPath, basicTest) {
TEST(TestPath, fill) {
esvg::Document doc;
#if 0
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg width='64' height='64'>"
" <g transform='matrix(1.2,0,0,1.2,-579.7336,-567.9832)'>"
"<svg height='100' width='100'>"
" <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'"
" style='fill:#F00;fill-rule:evenodd;stroke:#0000' />"
" </g>"
" fill='red' />"
"</svg>");
#else
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg width='64' height='64'>"
" <g transform='matrix(1.2,0,0,1.2,-579.7336,-567.9832)'>"
" <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'"
" style='fill:#000;stroke:#00F;stroke-width:5;fill-rule:evenodd' />"
" </g>"
"</svg>");
#endif
doc.generateAnImage(128, 128);
doc.generateAnImage(ivec2(100, 100), "TestPath_fill.ppm");
}
TEST(TestPath, stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <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");
}
TEST(TestPath, fill_and_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <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");
}

37
test/testPolygon.cpp Normal file
View File

@ -0,0 +1,37 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <esvg/esvg.h>
TEST(TestPolygon, fill) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<svg height='100' width='100'>"
" <polygon points='50,10 90,50 10,80' fill='red' />"
"</svg>");
doc.generateAnImage(ivec2(100, 100), "TestPolygon_fill.ppm");
}
TEST(TestPolygon, stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestPolygon, fill_and_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}

0
test/testPolyline.cpp Normal file
View File

64
test/testRectangle.cpp Normal file
View File

@ -0,0 +1,64 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <esvg/esvg.h>
TEST(TestRectangle, fill) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestRectangle, stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestRectangle, fill_and_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestRectangle, corned_fill) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestRectangle, corned_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}
TEST(TestRectangle, corned_fill_and_stroke) {
esvg::Document doc;
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
"<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");
}