diff --git a/Sources/libetk/etk/File.cpp b/Sources/libetk/etk/File.cpp index ca9ef56d..298d2a35 100644 --- a/Sources/libetk/etk/File.cpp +++ b/Sources/libetk/etk/File.cpp @@ -228,18 +228,18 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ m_folder = ""; m_shortFilename = ""; m_lineNumberOpen = 0; - TK_DEBUG("1 :Set Name : " << newFilename ); + TK_VERBOSE("1 :Set Name : " << newFilename ); etk::UString destFilename; if (newFilename.Size() == 0) { destFilename = "no-name"; } else { destFilename = newFilename; } - TK_DEBUG("2 : Get file Name : " << destFilename << "start with '/'=" << destFilename.StartWith('/')); + TK_VERBOSE("2 : Get file Name : " << destFilename << "start with '/'=" << destFilename.StartWith('/')); if (true == destFilename.StartWith('/')) { m_type = etk::FILE_TYPE_DIRECT; if (type != etk::FILE_TYPE_DIRECT) { - TK_DEBUG("Incompatible type with a file=\"" << newFilename << "\" ==> force it in direct mode ..."); + TK_VERBOSE("Incompatible type with a file=\"" << newFilename << "\" ==> force it in direct mode ..."); } } else { if (type == etk::FILE_TYPE_DIRECT) { @@ -262,14 +262,14 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ } } bool needUnpack = false; - #if ETK_DEBUG_LEVEL > 2 + #if ETK_DEBUG_LEVEL > 3 char *mode = NULL; #endif switch (m_type) { case etk::FILE_TYPE_DATA: { - #if ETK_DEBUG_LEVEL > 2 + #if ETK_DEBUG_LEVEL > 3 mode = "FILE_TYPE_DATA"; #endif #if defined(DATA_IN_APK) @@ -287,7 +287,7 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ if (-1 == m_idZipFile) { TK_ERROR("File Does not existed ... in APK : \"" << tmpFilename << "\""); } else { - TK_INFO("File existed ... in APK : \"" << tmpFilename << "\" ==> id=" << m_idZipFile); + TK_VERBOSE("File existed ... in APK : \"" << tmpFilename << "\" ==> id=" << m_idZipFile); } #else //etk::UString tmpFilename = destFilename; @@ -298,7 +298,7 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ break; case etk::FILE_TYPE_USER_DATA: { - #if ETK_DEBUG_LEVEL > 2 + #if ETK_DEBUG_LEVEL > 3 mode = "FILE_TYPE_USER_DATA"; #endif etk::UString tmpFilename = destFilename; @@ -309,7 +309,7 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ break; case etk::FILE_TYPE_CACHE: { - #if ETK_DEBUG_LEVEL > 2 + #if ETK_DEBUG_LEVEL > 3 mode = "FILE_TYPE_CACHE"; #endif etk::UString tmpFilename = destFilename; @@ -320,13 +320,13 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ break; default: // nothing to do ... - #if ETK_DEBUG_LEVEL > 2 + #if ETK_DEBUG_LEVEL > 3 mode = "FILE_TYPE_DIRECT"; #endif needUnpack = true; break; } - TK_DEBUG("3 : Get file Name : " << destFilename ); + TK_VERBOSE("3 : Get file Name : " << destFilename ); if (true == needUnpack) { // Get the real Path of the current File ok = realpath(destFilename.Utf8Data(), buf); @@ -336,10 +336,10 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ // Get the FileName etk::UString tmpFilename = destFilename.Extract(lastPos+1); destFilename.Remove(lastPos, destFilename.Size() - lastPos); - TK_DEBUG("try to find :\"" << destFilename << "\" / \"" << tmpFilename << "\" "); + TK_VERBOSE("try to find :\"" << destFilename << "\" / \"" << tmpFilename << "\" "); ok = realpath(destFilename.Utf8Data(), buf); if (!ok) { - TK_DEBUG("Can not find real Path name of \"" << destFilename << "\""); + TK_VERBOSE("Can not find real Path name of \"" << destFilename << "\""); m_shortFilename = tmpFilename; m_folder = destFilename; } else { @@ -348,7 +348,7 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ m_folder = destFilename; } } else { - TK_DEBUG("file : \"" << destFilename << "\" ==> No data???"); + TK_VERBOSE("file : \"" << destFilename << "\" ==> No data???"); // Basic ERROR ... m_shortFilename = destFilename; } @@ -360,7 +360,7 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ m_folder = destFilename.Extract(0, lastPos); } else { // Basic ERROR ... - TK_DEBUG("file : \"" << destFilename << "\" ==> No data???"); + TK_VERBOSE("file : \"" << destFilename << "\" ==> No data???"); m_shortFilename = destFilename; } } @@ -371,11 +371,11 @@ void etk::File::SetCompleateName(etk::UString &newFilename, etk::FileType_te typ m_folder = destFilename.Extract(0, lastPos); } else { // Basic ERROR ... - TK_DEBUG("file : \"" << destFilename << "\" ==> No data???"); + TK_VERBOSE("file : \"" << destFilename << "\" ==> No data???"); m_shortFilename = destFilename; } } - TK_DEBUG("Set FileName :\"" << m_folder << "\" / \"" << m_shortFilename << "\" mode=" << mode); + TK_VERBOSE("Set FileName :\"" << m_folder << "\" / \"" << m_shortFilename << "\" mode=" << mode); } int32_t etk::File::GetLineNumber(void) @@ -431,7 +431,7 @@ bool etk::File::LoadDataZip(void) struct zip_stat zipFileProperty; zip_stat_init(&zipFileProperty); zip_stat_index(s_APKArchive, m_idZipFile, 0, &zipFileProperty); - TK_DEBUG("LOAD data from the files : \"" << GetCompleateName() << "\""); + TK_VERBOSE("LOAD data from the files : \"" << GetCompleateName() << "\""); /* TK_DEBUG(" name=" << zipFileProperty.name); TK_DEBUG(" index=" << zipFileProperty.index); diff --git a/Sources/libparsersvg/parserSVG/Base.cpp b/Sources/libparsersvg/parserSVG/Base.cpp index 131a8dac..72bbdff9 100644 --- a/Sources/libparsersvg/parserSVG/Base.cpp +++ b/Sources/libparsersvg/parserSVG/Base.cpp @@ -113,8 +113,8 @@ void svg::Base::ParsePosition(const TiXmlNode *node, coord2D_ts &pos, coord2D_ts { pos.x = 0; pos.y = 0; - size.x = m_paint.viewPort.x; - size.y = m_paint.viewPort.y; + size.x = 0; + size.y = 0; const char * content = node->ToElement()->Attribute("x"); if (NULL != content) { @@ -243,6 +243,7 @@ void svg::Base::ParsePaintAttr(const TiXmlNode *node) m_paint.stroke = ParseColor(outputValue); } else if (0 == strcmp(outputType, "stroke-width") ) { m_paint.strokeWidth = ParseLength(outputValue); + //SVG_ERROR(" input : \"" << outputValue << "\" ==> " <Row()<<") Circle \"r\" is negative"); return false; } + sizeMax.x = m_position.x + m_radius; + sizeMax.y = m_position.y + m_radius; return true; } @@ -92,11 +94,13 @@ void svg::Circle::AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTra // set the filling mode : myRenderer.m_rasterizer.filling_rule((m_paint.flagEvenOdd)?agg::fill_even_odd:agg::fill_non_zero); - agg::conv_transform trans(myCircle, mtx); - myRenderer.m_rasterizer.add_path(trans); - agg::render_scanlines(myRenderer.m_rasterizer, myRenderer.m_scanLine, *myRenderer.m_renderArea); + if (m_paint.fill.alpha != 0x00) { + agg::conv_transform trans(myCircle, mtx); + myRenderer.m_rasterizer.add_path(trans); + agg::render_scanlines(myRenderer.m_rasterizer, myRenderer.m_scanLine, *myRenderer.m_renderArea); + } - if (m_paint.strokeWidth > 0) { + if (m_paint.strokeWidth > 0 && m_paint.stroke.alpha!=0x00 ) { myRenderer.m_renderArea->color(agg::rgba8(m_paint.stroke.red, m_paint.stroke.green, m_paint.stroke.blue, m_paint.stroke.alpha)); // Drawing as an outline agg::conv_stroke myCircleStroke(myCircle); diff --git a/Sources/libparsersvg/parserSVG/Circle.h b/Sources/libparsersvg/parserSVG/Circle.h index 5aa7ce17..9dc590da 100644 --- a/Sources/libparsersvg/parserSVG/Circle.h +++ b/Sources/libparsersvg/parserSVG/Circle.h @@ -37,7 +37,7 @@ namespace svg public: Circle(PaintState parentPaintState); ~Circle(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); virtual void AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTrans); }; diff --git a/Sources/libparsersvg/parserSVG/Ellipse.cpp b/Sources/libparsersvg/parserSVG/Ellipse.cpp index ab361eef..50bdd171 100644 --- a/Sources/libparsersvg/parserSVG/Ellipse.cpp +++ b/Sources/libparsersvg/parserSVG/Ellipse.cpp @@ -37,7 +37,7 @@ svg::Ellipse::~Ellipse(void) } -bool svg::Ellipse::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Ellipse::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { ParseTransform(node); ParsePaintAttr(node); @@ -72,6 +72,8 @@ bool svg::Ellipse::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) SVG_ERROR("(l "<Row()<<") Ellipse \"ry\" is not present"); return false; } + sizeMax.x = m_c.x + m_r.x; + sizeMax.y = m_c.y + m_r.y; return true; } @@ -95,11 +97,13 @@ void svg::Ellipse::AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTr // set the filling mode : myRenderer.m_rasterizer.filling_rule((m_paint.flagEvenOdd)?agg::fill_even_odd:agg::fill_non_zero); - agg::conv_transform trans(myEllipse, mtx); - myRenderer.m_rasterizer.add_path(trans); - agg::render_scanlines(myRenderer.m_rasterizer, myRenderer.m_scanLine, *myRenderer.m_renderArea); + if (m_paint.fill.alpha != 0x00) { + agg::conv_transform trans(myEllipse, mtx); + myRenderer.m_rasterizer.add_path(trans); + agg::render_scanlines(myRenderer.m_rasterizer, myRenderer.m_scanLine, *myRenderer.m_renderArea); + } - if (m_paint.strokeWidth > 0) { + if (m_paint.strokeWidth > 0 && m_paint.stroke.alpha!=0x00 ) { myRenderer.m_renderArea->color(agg::rgba8(m_paint.stroke.red, m_paint.stroke.green, m_paint.stroke.blue, m_paint.stroke.alpha)); // Drawing as an outline agg::conv_stroke myEllipseStroke(myEllipse); diff --git a/Sources/libparsersvg/parserSVG/Ellipse.h b/Sources/libparsersvg/parserSVG/Ellipse.h index d297bee1..0a6f6780 100644 --- a/Sources/libparsersvg/parserSVG/Ellipse.h +++ b/Sources/libparsersvg/parserSVG/Ellipse.h @@ -37,7 +37,7 @@ namespace svg public: Ellipse(PaintState parentPaintState); ~Ellipse(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); virtual void AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTrans); }; diff --git a/Sources/libparsersvg/parserSVG/Group.cpp b/Sources/libparsersvg/parserSVG/Group.cpp index 1e3da2d8..b6832b43 100644 --- a/Sources/libparsersvg/parserSVG/Group.cpp +++ b/Sources/libparsersvg/parserSVG/Group.cpp @@ -46,7 +46,7 @@ svg::Group::~Group(void) } -bool svg::Group::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Group::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { // parse ... coord2D_ts pos; @@ -61,6 +61,9 @@ bool svg::Group::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) SVG_VERBOSE("parsed G2. trans : (" << m_transformMatrix.sx << "," << m_transformMatrix.shy << "," << m_transformMatrix.shx << "," << m_transformMatrix.sy << "," << m_transformMatrix.tx << "," << m_transformMatrix.ty << ")"); + sizeMax.x = 0; + sizeMax.y = 0; + coord2D_ts tmpPos; // parse all sub node : for(TiXmlNode * child = node->FirstChild(); NULL != child; child = child->NextSibling() ) { svg::Base *elementParser = NULL; @@ -94,11 +97,13 @@ bool svg::Group::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) if (NULL == elementParser) { SVG_ERROR("(l "<Row()<<") error on node: \""<Parse(child, m_transformMatrix)) { + if (false == elementParser->Parse(child, m_transformMatrix, tmpPos)) { SVG_ERROR("(l "<Row()<<") error on node: \""<& o float element; char spacer[10]; int32_t nbElementRead; - while(sscanf(&input[iii], "%1[, ]%f%n", spacer, &element, &nbElementRead) == 2) { - SVG_DEBUG("Find element : " << element); + while( sscanf(&input[iii], "%1[, ]%f%n", spacer, &element, &nbElementRead) == 2 + || sscanf(&input[iii], "%f%n", &element, &nbElementRead) == 1) { + SVG_VERBOSE("Find element : " << element); outputList.PushBack(element); iii += nbElementRead; } @@ -72,7 +78,7 @@ const char * extractCmd(const char * input, char& cmd, etk::VectorType& o return outputPointer; } -bool svg::Path::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Path::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { ParseTransform(node); ParsePaintAttr(node); @@ -80,18 +86,13 @@ bool svg::Path::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) // add the property of the parrent modifications ... m_transformMatrix *= parentTrans; - //m_listElement const char *elementXML = node->ToElement()->Attribute("d"); if (NULL == elementXML) { SVG_ERROR("(l "<Row()<<") path: missing 'p' attribute"); return false; } - SVG_DEBUG("Parse Path : \"" << elementXML << "\""); - - coord2D_ts currentPos; - currentPos.x = 0; - currentPos.y = 0; + SVG_VERBOSE("Parse Path : \"" << elementXML << "\""); char command; etk::VectorType listDot; @@ -99,8 +100,184 @@ bool svg::Path::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) for( const char *sss=extractCmd(elementXML, command, listDot); NULL != sss; sss=extractCmd(sss, command, listDot) ) { - - // later ... + pathBasic_ts pathElement; + memset(&pathElement, 0, 1*sizeof(pathBasic_ts)); + switch(command) { + case 'M': // Move To (absolute) + case 'L': // Line To (absolute) + case 'V': // Vertical Line To (absolute) + case 'H': // Horizantal Line To (absolute) + case 'Q': // Quadratic Bezier curve (absolute) + case 'T': // smooth quadratic Bezier curve to (absolute) + case 'C': // curve to (absolute) + case 'S': // smooth curve to (absolute) + case 'A': // elliptical Arc (absolute) + case 'Z': // closepath (absolute) + pathElement.relative = false; + break; + default : // else (relative) + pathElement.relative = true; + break; + } + switch(command) { + case 'M': // Move To (absolute) + case 'm': // Move To (relative) + // 2 Elements ... + if(listDot.Size()%2 != 0) { + SVG_WARNING("the PATH command "<< command << " has not the good number of element = " << listDot.Size() ); + break; + } + pathElement.cmd = svg::PATH_ENUM_MOVETO; + for(int32_t iii=0; iiicolor(agg::rgba8(m_paint.fill.red, m_paint.fill.green, m_paint.fill.blue, m_paint.fill.alpha)); + + agg::path_storage path; + path.start_new_path(); + + + for(int32_t iii=0; iii curve(path); + if (m_paint.fill.alpha != 0x00) { + agg::conv_transform, agg::trans_affine> trans(curve, 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); + } + if (m_paint.strokeWidth > 0 && m_paint.stroke.alpha!=0x00 ) { + myRenderer.m_renderArea->color(agg::rgba8(m_paint.stroke.red, m_paint.stroke.green, m_paint.stroke.blue, m_paint.stroke.alpha)); + // Drawing as an outline + agg::conv_stroke > myPolygonStroke(curve); + myPolygonStroke.width(m_paint.strokeWidth); + agg::conv_transform >, agg::trans_affine> transStroke(myPolygonStroke, mtx); + // set the filling mode : + myRenderer.m_rasterizer.filling_rule(agg::fill_non_zero); + myRenderer.m_rasterizer.add_path(transStroke); + agg::render_scanlines(myRenderer.m_rasterizer, myRenderer.m_scanLine, *myRenderer.m_renderArea); + } +} + + +void svg::Path::AbstractMoveTo(agg::path_storage& path, bool rel, double x, double y) +{ + if(true == rel) { + path.rel_to_abs(&x, &y); + } + path.move_to(x, y); +} + +void svg::Path::AbstractLineTo(agg::path_storage& path, bool rel, double x, double y) +{ + if(true == rel) { + path.rel_to_abs(&x, &y); + } + path.line_to(x, y); +} + +void svg::Path::AbstractHLineTo(agg::path_storage& path, bool rel, double x) +{ + double x2 = 0.0; + double y2 = 0.0; + if(0!=path.total_vertices()) { + path.vertex(path.total_vertices() - 1, &x2, &y2); + if(true == rel) { + x += x2; + } + path.line_to(x, y2); + } +} + +void svg::Path::AbstractVLineTo(agg::path_storage& path, bool rel, double y) +{ + double x2 = 0.0; + double y2 = 0.0; + if(path.total_vertices()) { + path.vertex(path.total_vertices() - 1, &x2, &y2); + if(true == rel) { + y += y2; + } + path.line_to(x2, y); + } +} + +void svg::Path::AbstractCurve3(agg::path_storage& path, bool rel, double x1, double y1, double x, double y) +{ + if(true == rel) { + path.rel_to_abs(&x1, &y1); + path.rel_to_abs(&x, &y); + } + path.curve3(x1, y1, x, y); +} + +void svg::Path::AbstractCurve3(agg::path_storage& path, bool rel, double x, double y) +{ + if(true == rel) { + path.curve3_rel(x, y); + } else { + path.curve3(x, y); + } +} + +void svg::Path::AbstractCurve4(agg::path_storage& path, bool rel, double x1, double y1, double x2, double y2, double x, double y) +{ + if(true == rel) { + path.rel_to_abs(&x1, &y1); + path.rel_to_abs(&x2, &y2); + path.rel_to_abs(&x, &y); + } + path.curve4(x1, y1, x2, y2, x, y); +} + +void svg::Path::AbstractCurve4(agg::path_storage& path, bool rel, double x2, double y2, double x, double y) +{ + if(true == rel) { + path.curve4_rel(x2, y2, x, y); + } else { + path.curve4(x2, y2, x, y); + } +} + +void svg::Path::AbstractCloseSubpath(agg::path_storage& path) +{ + path.end_poly(agg::path_flags_close); +} diff --git a/Sources/libparsersvg/parserSVG/Path.h b/Sources/libparsersvg/parserSVG/Path.h index 34eb9de0..6f88adf3 100644 --- a/Sources/libparsersvg/parserSVG/Path.h +++ b/Sources/libparsersvg/parserSVG/Path.h @@ -26,13 +26,16 @@ #define __SVG_PATH_H__ #include +#include namespace svg { typedef enum { PATH_ENUM_STOP, - PATH_ENUM_GOTO, + PATH_ENUM_MOVETO, PATH_ENUM_LINETO, + PATH_ENUM_LINETO_H, + PATH_ENUM_LINETO_V, PATH_ENUM_CURVETO, PATH_ENUM_SMOTH_CURVETO, PATH_ENUM_BEZIER_CURVETO, @@ -42,45 +45,8 @@ namespace svg typedef struct { pathEnum_te cmd; - union { - struct{ - etkFloat_t x; - etkFloat_t y; - } position_s; - struct{ - etkFloat_t x1; - etkFloat_t y1; - etkFloat_t x2; - etkFloat_t y2; - etkFloat_t x3; - etkFloat_t y3; - }curveto_s; - struct{ - etkFloat_t x1; - etkFloat_t y1; - etkFloat_t x2; - etkFloat_t y2; - }shorthandSmoothCurveto_s; - struct{ - etkFloat_t x1; - etkFloat_t y1; - etkFloat_t x2; - etkFloat_t y2; - }quadraticBezierCurveto_s; - struct{ - etkFloat_t x; - etkFloat_t y; - } shorthandSmoothQuadraticBezierCurveto_s; - struct{ - etkFloat_t rx; - etkFloat_t ry; - etkFloat_t rotation; - etkFloat_t large_arc; - etkFloat_t sweep; - etkFloat_t x; - etkFloat_t y; - }ellipticArc_s; - }; + bool relative; + etkFloat_t element[7]; }pathBasic_ts; class Path : public svg::Base @@ -90,8 +56,19 @@ namespace svg public: Path(PaintState parentPaintState); ~Path(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); + virtual void AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTrans); + private: + void AbstractMoveTo(agg::path_storage& path, bool rel, double x, double y); + void AbstractLineTo(agg::path_storage& path, bool rel, double x, double y); + void AbstractHLineTo(agg::path_storage& path, bool rel, double x); + void AbstractVLineTo(agg::path_storage& path, bool rel, double y); + void AbstractCurve3(agg::path_storage& path, bool rel, double x1, double y1, double x, double y); + void AbstractCurve3(agg::path_storage& path, bool rel, double x, double y); + void AbstractCurve4(agg::path_storage& path, bool rel, double x1, double y1, double x2, double y2, double x, double y); + void AbstractCurve4(agg::path_storage& path, bool rel, double x2, double y2, double x, double y); + void AbstractCloseSubpath(agg::path_storage& path); }; }; diff --git a/Sources/libparsersvg/parserSVG/Polygon.cpp b/Sources/libparsersvg/parserSVG/Polygon.cpp index e62d5e80..62407e4d 100644 --- a/Sources/libparsersvg/parserSVG/Polygon.cpp +++ b/Sources/libparsersvg/parserSVG/Polygon.cpp @@ -37,7 +37,7 @@ svg::Polygon::~Polygon(void) } -bool svg::Polygon::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Polygon::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { ParseTransform(node); ParsePaintAttr(node); @@ -54,6 +54,8 @@ bool svg::Polygon::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) SVG_ERROR("(l "<Row()<<") polygon: missing points attribute"); return false; } + sizeMax.x = 0; + sizeMax.y = 0; SVG_VERBOSE("Parse polygon : \"" << sss << "\""); while ('\0' != sss[0]) { coord2D_ts pos; @@ -61,6 +63,8 @@ bool svg::Polygon::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) if (sscanf(sss, "%f,%f %n", &pos.x, &pos.y, &n) == 2) { m_listPoint.PushBack(pos); sss += n; + sizeMax.x = etk_max(sizeMax.x, pos.x); + sizeMax.y = etk_max(sizeMax.y, pos.y); } else { break; } @@ -85,19 +89,44 @@ void svg::Polygon::AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTr path.line_to(m_listPoint[iii].x, m_listPoint[iii].y); } path.close_polygon(); - + /* + // configure the end of the line : + switch (m_paint.lineCap) { + case svg::LINECAP_SQUARE: + path.line_cap(agg::square_cap); + break; + case svg::LINECAP_ROUND: + path.line_cap(agg::round_cap); + break; + default: // svg::LINECAP_BUTT + path.line_cap(agg::butt_cap); + break; + } + switch (m_paint.lineJoin) { + case svg::LINEJOIN_BEVEL: + path.line_join(agg::bevel_join); + break; + case svg::LINEJOIN_ROUND: + path.line_join(agg::round_join); + break; + default: // svg::LINEJOIN_MITER + path.line_join(agg::miter_join); + break; + } + */ agg::trans_affine mtx = m_transformMatrix; mtx *= basicTrans; - agg::conv_transform trans(path, 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); + if (m_paint.fill.alpha != 0x00) { + agg::conv_transform trans(path, 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); + } - - if (m_paint.strokeWidth > 0) { + if (m_paint.strokeWidth > 0 && m_paint.stroke.alpha!=0x00 ) { myRenderer.m_renderArea->color(agg::rgba8(m_paint.stroke.red, m_paint.stroke.green, m_paint.stroke.blue, m_paint.stroke.alpha)); // Drawing as an outline agg::conv_stroke myPolygonStroke(path); diff --git a/Sources/libparsersvg/parserSVG/Polygon.h b/Sources/libparsersvg/parserSVG/Polygon.h index aad6a006..49ec4318 100644 --- a/Sources/libparsersvg/parserSVG/Polygon.h +++ b/Sources/libparsersvg/parserSVG/Polygon.h @@ -42,7 +42,7 @@ namespace svg public: Polygon(PaintState parentPaintState); ~Polygon(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); virtual void AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTrans); }; diff --git a/Sources/libparsersvg/parserSVG/Polyline.cpp b/Sources/libparsersvg/parserSVG/Polyline.cpp index b5095e86..b978a682 100644 --- a/Sources/libparsersvg/parserSVG/Polyline.cpp +++ b/Sources/libparsersvg/parserSVG/Polyline.cpp @@ -37,7 +37,7 @@ svg::Polyline::~Polyline(void) } -bool svg::Polyline::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Polyline::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { // line must have a minimum size... m_paint.strokeWidth = 1; @@ -52,12 +52,16 @@ bool svg::Polyline::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) SVG_ERROR("(l "<Row()<<") polyline: missing points attribute"); return false; } + sizeMax.x = 0; + sizeMax.y = 0; SVG_VERBOSE("Parse polyline : \"" << sss << "\""); while ('\0' != sss[0]) { coord2D_ts pos; int32_t n; if (sscanf(sss, "%f,%f %n", &pos.x, &pos.y, &n) == 2) { m_listPoint.PushBack(pos); + sizeMax.x = etk_max(sizeMax.x, pos.x); + sizeMax.y = etk_max(sizeMax.y, pos.y); sss += n; } else { break; @@ -80,7 +84,31 @@ void svg::Polyline::AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicT for( int32_t iii=1; iii< m_listPoint.Size(); iii++) { path.line_to(m_listPoint[iii].x, m_listPoint[iii].y); } - //path.close_polygon(); + /* + // configure the end of the line : + switch (m_paint.lineCap) { + case svg::LINECAP_SQUARE: + path.line_cap(agg::square_cap); + break; + case svg::LINECAP_ROUND: + path.line_cap(agg::round_cap); + break; + default: // svg::LINECAP_BUTT + path.line_cap(agg::butt_cap); + break; + } + switch (m_paint.lineJoin) { + case svg::LINEJOIN_BEVEL: + path.line_join(agg::bevel_join); + break; + case svg::LINEJOIN_ROUND: + path.line_join(agg::round_join); + break; + default: // svg::LINEJOIN_MITER + path.line_join(agg::miter_join); + break; + } + */ agg::trans_affine mtx = m_transformMatrix; mtx *= basicTrans; diff --git a/Sources/libparsersvg/parserSVG/Polyline.h b/Sources/libparsersvg/parserSVG/Polyline.h index 92b2f86c..322168ce 100644 --- a/Sources/libparsersvg/parserSVG/Polyline.h +++ b/Sources/libparsersvg/parserSVG/Polyline.h @@ -37,7 +37,7 @@ namespace svg public: Polyline(PaintState parentPaintState); ~Polyline(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); virtual void AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTrans); }; diff --git a/Sources/libparsersvg/parserSVG/Rectangle.cpp b/Sources/libparsersvg/parserSVG/Rectangle.cpp index 62c2a352..373b0d6c 100644 --- a/Sources/libparsersvg/parserSVG/Rectangle.cpp +++ b/Sources/libparsersvg/parserSVG/Rectangle.cpp @@ -42,7 +42,7 @@ svg::Rectangle::~Rectangle(void) } -bool svg::Rectangle::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Rectangle::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { m_position.x = 0.0; m_position.y = 0.0; @@ -67,6 +67,8 @@ bool svg::Rectangle::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) if (NULL != content) { m_roundedCorner.y = ParseLength(content); } + sizeMax.x = m_position.x + m_size.x + m_paint.strokeWidth; + sizeMax.y = m_position.y + m_size.y + m_paint.strokeWidth; return true; } @@ -79,7 +81,7 @@ void svg::Rectangle::AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basic { myRenderer.m_renderArea->color(agg::rgba8(m_paint.fill.red, m_paint.fill.green, m_paint.fill.blue, m_paint.fill.alpha)); // Creating a rounded rectangle - agg::rounded_rect rect_r(m_position.x, m_position.y, m_size.x, m_size.y, m_roundedCorner.x); + 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(); @@ -87,13 +89,15 @@ void svg::Rectangle::AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basic // herited modifications ... mtx *= basicTrans; - agg::conv_transform 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); + if (m_paint.fill.alpha != 0x00) { + agg::conv_transform 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); + } - if (m_paint.strokeWidth > 0) { + if (m_paint.strokeWidth > 0 && m_paint.stroke.alpha!=0x00 ) { myRenderer.m_renderArea->color(agg::rgba8(m_paint.stroke.red, m_paint.stroke.green, m_paint.stroke.blue, m_paint.stroke.alpha)); // Drawing as an outline agg::conv_stroke rect_p(rect_r); diff --git a/Sources/libparsersvg/parserSVG/Rectangle.h b/Sources/libparsersvg/parserSVG/Rectangle.h index b2db7888..ffcfa3f9 100644 --- a/Sources/libparsersvg/parserSVG/Rectangle.h +++ b/Sources/libparsersvg/parserSVG/Rectangle.h @@ -38,7 +38,7 @@ namespace svg public: Rectangle(PaintState parentPaintState); ~Rectangle(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); virtual void AggDraw(svg::Renderer& myRenderer, agg::trans_affine& basicTrans); }; diff --git a/Sources/libparsersvg/parserSVG/Renderer.h b/Sources/libparsersvg/parserSVG/Renderer.h index 138754a2..bea36c1e 100644 --- a/Sources/libparsersvg/parserSVG/Renderer.h +++ b/Sources/libparsersvg/parserSVG/Renderer.h @@ -40,13 +40,25 @@ namespace svg { - #define MATRIX_SIZE (6) + typedef enum { + LINECAP_BUTT, + LINECAP_ROUND, + LINECAP_SQUARE, + } lineCap_te; + typedef enum { + LINEJOIN_MITER, + LINEJOIN_ROUND, + LINEJOIN_BEVEL, + } lineJoin_te; + class PaintState { public: color8_ts fill; color8_ts stroke; etkFloat_t strokeWidth; bool flagEvenOdd; + lineCap_te lineCap; + lineJoin_te lineJoin; coord2D_ts viewPort; }; diff --git a/Sources/libparsersvg/parserSVG/Text.cpp b/Sources/libparsersvg/parserSVG/Text.cpp index b6820d17..6f0c01be 100644 --- a/Sources/libparsersvg/parserSVG/Text.cpp +++ b/Sources/libparsersvg/parserSVG/Text.cpp @@ -35,8 +35,10 @@ svg::Text::~Text(void) } -bool svg::Text::Parse(TiXmlNode * node, agg::trans_affine& parentTrans) +bool svg::Text::Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax) { + sizeMax.x = 0; + sizeMax.y = 0; SVG_ERROR("NOT IMPLEMENTED"); return false; } diff --git a/Sources/libparsersvg/parserSVG/Text.h b/Sources/libparsersvg/parserSVG/Text.h index fdae3a99..2c5f0fcd 100644 --- a/Sources/libparsersvg/parserSVG/Text.h +++ b/Sources/libparsersvg/parserSVG/Text.h @@ -36,7 +36,7 @@ namespace svg public: Text(PaintState parentPaintState); ~Text(void); - virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans); + virtual bool Parse(TiXmlNode * node, agg::trans_affine& parentTrans, coord2D_ts& sizeMax); virtual void Display(int32_t spacing); }; }; diff --git a/Sources/libparsersvg/parserSVG/parserSVG.cpp b/Sources/libparsersvg/parserSVG/parserSVG.cpp index 9a0205f0..d9f1d84f 100644 --- a/Sources/libparsersvg/parserSVG/parserSVG.cpp +++ b/Sources/libparsersvg/parserSVG/parserSVG.cpp @@ -62,11 +62,14 @@ svg::Parser::Parser(etk::File fileName) m_paint.stroke.blue = 0xFF; m_paint.stroke.alpha = 0; - m_paint.strokeWidth = 0xFF; - m_paint.viewPort.x = 0xFF; - m_paint.viewPort.y = 0xFF; + m_paint.strokeWidth = 1.0; + m_paint.viewPort.x = 255; + m_paint.viewPort.y = 255; m_paint.flagEvenOdd = false; - + m_paint.lineJoin = svg::LINEJOIN_MITER; + m_paint.lineCap = svg::LINECAP_BUTT; + m_size.x = 0.0; + m_size.y = 0.0; // Start loading the XML : SVG_DEBUG("open file (SVG) \"" << m_fileName << "\""); @@ -111,13 +114,17 @@ svg::Parser::Parser(etk::File fileName) } // parse ... coord2D_ts pos; - coord2D_ts size; ParseTransform(root); - ParsePosition(root, pos, size); + ParsePosition(root, pos, m_size); ParsePaintAttr(root); SVG_VERBOSE("parsed .ROOT trans : (" << m_transformMatrix.sx << "," << m_transformMatrix.shy << "," << m_transformMatrix.shx << "," << m_transformMatrix.sy << "," << m_transformMatrix.tx << "," << m_transformMatrix.ty << ")"); + coord2D_ts maxSize; + maxSize.x = 0.0; + maxSize.y = 0.0; + + coord2D_ts size; // parse all sub node : for(TiXmlNode * child = root->FirstChild(); NULL != child; child = child->NextSibling() ) { svg::Base *elementParser = NULL; @@ -125,10 +132,15 @@ svg::Parser::Parser(etk::File fileName) // nothing to do, just proceed to next step } else { etk::UString localValue = child->Value(); + bool normalNoElement = false; if (localValue == "g") { elementParser = new svg::Group(m_paint); } else if (localValue == "a") { - // TODO ... + SVG_INFO("Note : 'a' balise is parsed like a g balise ..."); + elementParser = new svg::Group(m_paint); + } else if (localValue == "title") { + m_title = "TODO : set the title here ..."; + normalNoElement = true; } else if (localValue == "path") { elementParser = new svg::Path(m_paint); } else if (localValue == "rect") { @@ -146,24 +158,38 @@ svg::Parser::Parser(etk::File fileName) } else if (localValue == "text") { elementParser = new svg::Text(m_paint); } else { - SVG_ERROR("(l "<Row()<<") node not suported : \""<Row()<<") node not suported : \""<Row()<<") error on node: \""<Parse(child, m_transformMatrix)) { - SVG_ERROR("(l "<Row()<<") error on node: \""<Row()<<") error on node: \""<Parse(child, m_transformMatrix, size)) { + SVG_ERROR("(l "<Row()<<") error on node: \""<