/** ******************************************************************************* * @file parserSVG/parserSVG.cpp * @brief parserSVG : basic header of the SVG parser (Sources) * @author Edouard DUPIN * @date 18/03/2012 * @par Project * parserSVG * * @par Copyright * Copyright 2011 Edouard DUPIN, all right reserved * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY. * * Licence summary : * You can modify and redistribute the sources code and binaries. * You can send me the bug-fix * * Term of the licence in in the file licence.txt. * ******************************************************************************* */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include svg::Parser::Parser(etk::UString fileName) : m_renderedElement(NULL) { m_fileName = fileName; m_version = "0.0"; m_loadOK = true; m_paint.fill = (int32_t)0xFF0000FF; m_paint.stroke = (int32_t)0xFFFFFF00; m_paint.strokeWidth = 1.0; m_paint.viewPort.setValue(255,255); m_paint.flagEvenOdd = false; m_paint.lineJoin = svg::LINEJOIN_MITER; m_paint.lineCap = svg::LINECAP_BUTT; m_size.setValue(0,0); // Start loading the XML : SVG_DEBUG("open file (SVG) \"" << m_fileName << "\""); etk::FSNode tmpFile(m_fileName); // allocate the document in the stack TiXmlDocument XmlDocument; if (false == tmpFile.Exist()) { SVG_ERROR("File Does not exist : " << m_fileName); m_loadOK = false; return; } int64_t fileSize = tmpFile.FileSize(); if (0==fileSize) { SVG_ERROR("This file is empty : " << m_fileName); m_loadOK = false; return; } if (false == tmpFile.FileOpenRead()) { SVG_ERROR("Can not open the file : " << m_fileName); m_loadOK = false; return; } // allocate data char * fileBuffer = new char[fileSize+5]; if (NULL == fileBuffer) { SVG_ERROR("Error Memory allocation size=" << fileSize); m_loadOK = false; return; } memset(fileBuffer, 0, (fileSize+5)*sizeof(char)); // load data from the file : tmpFile.FileRead(fileBuffer, 1, fileSize); // close the file: tmpFile.FileClose(); // load the XML from the memory XmlDocument.Parse((const char*)fileBuffer, 0, TIXML_ENCODING_UTF8); TiXmlElement* root = XmlDocument.FirstChildElement( "svg" ); if (NULL == root ) { SVG_ERROR("(l ?) main node not find: \"svg\" in \"" << m_fileName << "\""); m_loadOK = false; } else { // get the svg version : const char *version = root->ToElement()->Attribute("version"); if (NULL != version) { m_version = version; } // parse ... vec2 pos(0,0); ParseTransform(root); 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 << ")"); vec2 maxSize(0,0); vec2 size(0,0); // parse all sub node : for(TiXmlNode * child = root->FirstChild(); NULL != child; child = child->NextSibling() ) { svg::Base *elementParser = NULL; if (child->Type()==TiXmlNode::TINYXML_COMMENT) { // 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") { 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") { elementParser = new svg::Rectangle(m_paint); } else if (localValue == "circle") { elementParser = new svg::Circle(m_paint); } else if (localValue == "ellipse") { elementParser = new svg::Ellipse(m_paint); } else if (localValue == "line") { elementParser = new svg::Line(m_paint); } else if (localValue == "polyline") { elementParser = new svg::Polyline(m_paint); } else if (localValue == "polygon") { elementParser = new svg::Polygon(m_paint); } else if (localValue == "text") { elementParser = new svg::Text(m_paint); } else if (localValue == "defs") { // Node ignore : must implement it later ... normalNoElement = true; } else if (localValue == "sodipodi:namedview") { // Node ignore : generaly inkscape data normalNoElement = true; } else if (localValue == "metadata") { // Node ignore : generaly inkscape data normalNoElement = true; } else { SVG_ERROR("(l "<Row()<<") node not suported : \""<Row()<<") error on node: \""<Parse(child, m_transformMatrix, size)) { SVG_ERROR("(l "<Row()<<") error on node: \""<WritePpm(tmpFileOut); } void svg::Parser::GenerateAnImage(int32_t sizeX, int32_t sizeY) { int32_t SizeX = sizeX; if (SizeX == 0) { SVG_ERROR("SizeX == 0 ==> set 64"); SizeX = 64; } int32_t SizeY = sizeY; if (SizeY == 0) { SVG_ERROR("SizeY == 0 ==> set 64"); SizeY = 64; } SVG_INFO("Generate size (" << SizeX << "," << SizeY << ")"); if(NULL != m_renderedElement) { delete(m_renderedElement); m_renderedElement = NULL; } m_renderedElement = new svg::Renderer(SizeX, SizeY); // create the first element matrix modification ... agg::trans_affine basicTrans; //basicTrans *= agg::trans_affine_translation(-g_base_dx, -g_base_dy); basicTrans *= agg::trans_affine_scaling(SizeX/m_size.x(), SizeY/m_size.y()); //basicTrans *= agg::trans_affine_rotation(g_angle);// + agg::pi); //basicTrans *= agg::trans_affine_skewing(2.0, 5.0); //basicTrans *= agg::trans_affine_translation(width*0.3, height/2); //basicTrans *= agg::trans_affine_translation(width/3, height/3); AggDraw(*m_renderedElement, basicTrans); /* etk::UString tmpFileOut = "zzz_out_test.ppm"; m_renderedElement->WritePpm(tmpFileOut); */ } void svg::Parser::GenerateAnImage(draw::Image& output) { GenerateAnImage(ivec2(m_size.x(),m_size.y()), output); } void svg::Parser::GenerateAnImage(ivec2 size, draw::Image& output) { GenerateAnImage(size.x(), size.y()); output.Resize(size); draw::Color tmpp(0,0,0,0); output.SetFillColor(tmpp); output.Clear(); if(NULL != m_renderedElement) { uint8_t* pointerOnData = m_renderedElement->GetDataPointer(); int32_t sizeData = m_renderedElement->GetDataSize(); uint8_t* tmpOut = (uint8_t*)output.GetTextureDataPointer(); memcpy(tmpOut, pointerOnData, sizeData); } } uint8_t* svg::Parser::GetPointerOnData(void) { if(NULL == m_renderedElement) { return NULL; } return m_renderedElement->GetDataPointer(); } uint32_t svg::Parser::GetSizeOnData(void) { if(NULL == m_renderedElement) { return 0; } return m_renderedElement->GetDataSize(); }