[DEV] support xlink::href in linear gradient

This commit is contained in:
Edouard DUPIN 2015-12-17 21:55:37 +01:00
parent 6b976bb9ea
commit 3bba1c8ba4
4 changed files with 64 additions and 8 deletions

View File

@ -10,6 +10,7 @@
#include <esvg/LinearGradient.h>
#include <esvg/render/Path.h>
#include <esvg/render/Weight.h>
#include <esvg/esvg.h>
#undef __class__
#define __class__ "LinearGradient"
@ -42,11 +43,21 @@ bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _eleme
std::string contentX = _element->getAttribute("x1");
std::string contentY = _element->getAttribute("y1");
m_pos1.set(contentX, contentY);
if ( contentX != ""
&& contentY != "") {
m_pos1.set(contentX, contentY);
}
contentX = _element->getAttribute("x2");
contentY = _element->getAttribute("y2");
m_pos2.set(contentX, contentY);
if ( contentX != ""
&& contentY != "") {
m_pos2.set(contentX, contentY);
}
// note: xlink:href is incompatible with subNode "stop"
m_href = _element->getAttribute("xlink:href");
if (m_href.size() != 0) {
m_href = std::string(m_href.begin()+1, m_href.end());
}
// parse all sub node :
for(int32_t iii=0; iii<_element->size() ; iii++) {
std::shared_ptr<exml::Element> child = _element->getElement(iii);
@ -83,6 +94,12 @@ bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _eleme
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;
}
@ -105,8 +122,25 @@ const esvg::Dimension& esvg::LinearGradient::getPosition2() {
return m_pos2;
}
const std::vector<std::pair<float, etk::Color<float,4>>>& esvg::LinearGradient::getColors() {
return m_data;
const std::vector<std::pair<float, etk::Color<float,4>>>& esvg::LinearGradient::getColors(esvg::Document* _document) {
if (m_href == "") {
return m_data;
}
if (_document == nullptr) {
ESVG_ERROR("Get nullptr input for document");
return m_data;
}
std::shared_ptr<esvg::Base> base = _document->getReference(m_href);
if (base == nullptr) {
ESVG_ERROR("Can not get base : '" << m_href << "'");
return m_data;
}
std::shared_ptr<esvg::LinearGradient> gradient = std::dynamic_pointer_cast<esvg::LinearGradient>(base);
if (gradient == nullptr) {
ESVG_ERROR("Can not cast in a linear gradient: '" << m_href << "' ==> wrong type");
return m_data;
}
return gradient->getColors(_document);
}

View File

@ -12,11 +12,13 @@
#include <esvg/Base.h>
namespace esvg {
class Document;
class LinearGradient : public esvg::Base {
private:
esvg::Dimension m_pos1; //!< gradient position x1 y1
esvg::Dimension m_pos2; //!< gradient position x2 y2
std::vector<std::pair<float, etk::Color<float,4>>> m_data;
std::string m_href; //!< in case of using a single gradient in multiple gradient, the gradient is store in an other element...
std::vector<std::pair<float, etk::Color<float,4>>> m_data; //!< incompatible with href
public:
LinearGradient(PaintState _parentPaintState);
~LinearGradient();
@ -26,7 +28,7 @@ namespace esvg {
public:
const esvg::Dimension& getPosition1();
const esvg::Dimension& getPosition2();
const std::vector<std::pair<float, etk::Color<float,4>>>& getColors();
const std::vector<std::pair<float, etk::Color<float,4>>>& getColors(esvg::Document* _document);
};
};

View File

@ -145,7 +145,7 @@ void esvg::render::DynamicColorLinear::generate(esvg::Document* _document) {
m_baseSize = vec2((m_pos1 - intersecX).length(),
(m_pos1 - intersecY).length());
// get all the colors
m_data = gradient->getColors();
m_data = gradient->getColors(_document);
}

View File

@ -167,3 +167,23 @@ TEST(TestGradientLinear, diag2scale) {
etk::FSNodeWriteAllData("TestGradientLinear_diag2scale.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestGradientLinear_diag2scale.bmp", g_visualDebug);
}
TEST(TestGradientLinear, internalHref) {
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
"<svg height='100' width='100'>\n"
" <defs>\n"
" <linearGradient id='grad2Values'>\n"
" <stop offset='0%' style='stop-color:rgb(255,0,0);stop-opacity:1' />\n"
" <stop offset='45%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n"
" <stop offset='55%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
" <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n"
" </linearGradient>\n"
" <linearGradient id='grad2' x1='0%' y1='100%' x2='100%' y2='0%' xlink:href='#grad2Values' />\n"
" </defs>\n"
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n"
"</svg>\n");
esvg::Document doc;
doc.parse(data);
etk::FSNodeWriteAllData("TestGradientLinear_internalHref.svg", data);
doc.generateAnImage(ivec2(100, 100), "TestGradientLinear_internalHref.bmp", g_visualDebug);
}