bool esvg::Polyline::parseXML(const exml::Element& _element, mat2& _parentTrans, vec2& _sizeMax) { // line must have a minimum size... m_paint.strokeWidth = 1; if (_element.exist() == false) { return false; } parseTransform(_element); parsePaintAttr(_element); // add the property of the parrent modifications ... m_transformMatrix *= _parentTrans; std::string sss1 = _element.attributes["points"]; if (sss1.size() == 0) { ESVG_ERROR("(l "<<_element.getPos()<<") polyline: missing points attribute"); return false; } _sizeMax.setValue(0,0); ESVG_VERBOSE("Parse polyline : \"" << sss1 << "\""); const char* sss = sss1.c_str(); while ('\0' != sss[0]) { vec2 pos; int32_t n; if (sscanf(sss, "%f,%f %n", &pos.m_floats[0], &pos.m_floats[1], &n) == 2) { m_listPoint.push_back(pos); _sizeMax.setValue(std::max(_sizeMax.x(), pos.x()), std::max(_sizeMax.y(), pos.y())); sss += n; } else { break; } } return true; }
bool esvg::Rectangle::parseXML(const exml::Element& _element, mat2& _parentTrans, vec2& _sizeMax) { if (_element.exist() == false) { return false; } 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); // add the property of the parrent modifications ... m_transformMatrix *= _parentTrans; parsePosition(_element, m_position, m_size); std::string content = _element.attributes["rx"]; if (content.size()!=0) { m_roundedCorner.setX(parseLength(content)); } content = _element.attributes["ry"]; if (content.size()!=0) { m_roundedCorner.setY(parseLength(content)); } _sizeMax.setValue(m_position.x() + m_size.x() + m_paint.strokeWidth, m_position.y() + m_size.y() + m_paint.strokeWidth); return true; }
void appl::Highlight::init(const std::string& _xmlFilename, const std::string& _colorFile) { gale::Resource::init(_xmlFilename); // keep color propertiy file : m_paintingProperties = appl::GlyphPainting::create(_colorFile); exml::Document doc; if (doc.load(_xmlFilename) == false) { APPL_ERROR(" can not load file XML : " << _xmlFilename); return; } exml::Element root = doc.nodes["EdnLang"]; if (root.exist() == false) { APPL_ERROR("(l ?) main node not find: 'EdnLang' ..."); return; } m_typeName = root.attributes["lang"]; int32_t level1 = 0; int32_t level2 = 0; // parse all the elements : for (const auto it : root.nodes) { const exml::Element child = it.toElement(); if (child.exist() == false) { // trash here all that is not element ... continue; } if (child.getValue() == "ext") { std::string myData = child.getText(); if (myData.size()!=0) { //HL_DEBUG("(l %d) node fined : %s=\"%s\"", child->Row(), child->Value() , myData); m_listExtentions.push_back(myData); } } else if (child.getValue() == "pass1") { // get sub Nodes ... for (const auto it2 : child.nodes) { const exml::Element passChild = it2.toElement(); if (passChild.exist() == false) { continue; } if (passChild.getValue() != "rule") { APPL_ERROR("(l "<< passChild.getPos() << ") node not suported : '"<< passChild.getValue() << "' must be [rule]" ); continue; } // Create the patern in list m_listHighlightPass1.push_back(HighlightPattern(m_paintingProperties, passChild, level1++)); } } else if (child.getValue() == "pass2") { // get sub Nodes ... for (const auto it2 : child.nodes) { const exml::Element passChild = it2.toElement(); if (passChild.exist() == false) { continue; } if (passChild.getValue() != "rule") { APPL_ERROR("(l "<< passChild.getPos() << ") node not suported : '"<< passChild.getValue() << "' must be [rule]" ); continue; } // Create the patern in list m_listHighlightPass2.push_back(HighlightPattern(m_paintingProperties, passChild, level2++)); } } else if (child.getValue() == "pass") { std::string attributeName = child.attributes["name"]; if (attributeName == "") { APPL_ERROR("Can not parse an element pass with no attribute name ... ligne=" << child.getPos()); continue; } m_listHighlightNamed.insert(std::pair<std::string, std::vector<HighlightPattern>>(attributeName, std::vector<HighlightPattern>())); auto it3 = m_listHighlightNamed.find(attributeName); int32_t level3=0; // get sub Nodes ... for (const auto it2 : child.nodes) { const exml::Element passChild = it2.toElement(); if (passChild.exist() == false) { continue; } if (passChild.getValue() != "rule") { APPL_ERROR("(l "<< passChild.getPos() << ") node not suported : '"<< passChild.getValue() << "' must be [rule]" ); continue; } // add element in the list it3->second.push_back(HighlightPattern(m_paintingProperties, passChild, level3++)); } } else { APPL_ERROR("(l "<< child.getPos() << ") node not suported : '"<< child.getValue() << "' must be [ext,pass1,pass2]" ); } } }
bool esvg::RadialGradient::parseXML(const exml::Element& _element, mat2& _parentTrans, vec2& _sizeMax) { // line must have a minimum size... //m_paint.strokeWidth = 1; if (_element.exist() == false) { return false; } // ---------------- get unique ID ---------------- m_id = _element.attributes["id"]; //parseTransform(_element); //parsePaintAttr(_element); // add the property of the parrent modifications ... m_transformMatrix *= _parentTrans; std::string contentX = _element.attributes["cx"]; std::string contentY = _element.attributes["cy"]; if ( contentX != "" && contentY != "") { m_center.set(contentX, contentY); } contentX = _element.attributes["r"]; if (contentX != "") { m_radius.set(contentX); } contentX = _element.attributes["fx"]; contentY = _element.attributes["fy"]; if ( contentX != "" && contentY != "") { m_focal.set(contentX, contentY); } contentX = _element.attributes["gradientUnits"]; if (contentX == "userSpaceOnUse") { m_unit = gradientUnits_userSpaceOnUse; } else { m_unit = gradientUnits_objectBoundingBox; if ( contentX.size() != 0 && contentX != "objectBoundingBox") { ESVG_ERROR("Parsing error of 'gradientUnits' ==> not suported value: '" << contentX << "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox"); } } contentX = _element.attributes["spreadMethod"]; if (contentX == "reflect") { m_spread = spreadMethod_reflect; } else if (contentX == "repeat") { m_spread = spreadMethod_repeat; } else { m_spread = spreadMethod_pad; if ( contentX.size() != 0 && contentX != "pad") { ESVG_ERROR("Parsing error of 'spreadMethod' ==> not suported value: '" << contentX << "' not in : {reflect/repeate/pad} use pad"); } } // note: xlink:href is incompatible with subNode "stop" m_href = _element.attributes["xlink:href"]; if (m_href.size() != 0) { m_href = std::string(m_href.begin()+1, m_href.end()); } // parse all sub node : for(auto it : _element.nodes) { exml::Element child = it.toElement(); if (child.exist() == false) { // can be a comment ... continue; } if (child.getValue() == "stop") { float offset = 100; etk::Color<float,4> stopColor = etk::color::none; std::string content = child.attributes["offset"]; if (content.size()!=0) { std::pair<float, enum esvg::distance> tmp = parseLength2(content); if (tmp.second == esvg::distance_pixel) { // special case ==> all time % then no type define ==> % in [0.0 .. 1.0] offset = tmp.first*100.0f; } else if (tmp.second != esvg::distance_pourcent) { ESVG_ERROR("offset : " << content << " res=" << tmp.first << "," << tmp.second << " Not support other than pourcent %"); } else { offset = tmp.first; } } content = child.attributes["stop-color"]; if (content.size()!=0) { stopColor = parseColor(content).first; ESVG_VERBOSE(" color : \"" << content << "\" == > " << stopColor); } content = child.attributes["stop-opacity"]; if (content.size()!=0) { float opacity = parseLength(content); opacity = std::avg(0.0f, opacity, 1.0f); stopColor.setA(opacity); ESVG_VERBOSE(" opacity : '" << content << "' == > " << stopColor); } m_data.push_back(std::pair<float, etk::Color<float,4>>(offset, stopColor)); } else { ESVG_ERROR("(l " << child.getPos() << ") node not suported : '" << child.getValue() << "' must be [stop]"); } } if (m_data.size() != 0) { if (m_href != "") { ESVG_ERROR("(l " << _element.getPos() << ") node can not have an xlink:href element with sub node named: stop ==> removing href"); m_href = ""; } } return true; }