[DEV] add support of radial gradient (partial)
This commit is contained in:
parent
8610d6491b
commit
dbbd996850
@ -67,7 +67,8 @@ void esvg::Dimension::set(std::string _config) {
|
||||
type = esvg::distance_meter;
|
||||
_config.erase(_config.size()-1, 1);
|
||||
} else {
|
||||
ESVG_CRITICAL("Can not parse dimention : \"" << _config << "\"");
|
||||
type = esvg::distance_pixel;
|
||||
ESVG_VERBOSE("default dimention type for: '" << _config << "' ==> pixel");
|
||||
return;
|
||||
}
|
||||
vec2 tmp = _config;
|
||||
@ -326,8 +327,8 @@ void esvg::Dimension1D::set(std::string _config) {
|
||||
type = esvg::distance_meter;
|
||||
_config.erase(_config.size()-1, 1);
|
||||
} else {
|
||||
ESVG_CRITICAL("Can not parse dimention : \"" << _config << "\"");
|
||||
return;
|
||||
type = esvg::distance_pixel;
|
||||
ESVG_VERBOSE("default dimention type for: '" << _config << "' ==> pixel");
|
||||
}
|
||||
float tmp = etk::string_to_float(_config);
|
||||
set(tmp, type);
|
||||
|
@ -105,7 +105,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
||||
}
|
||||
#ifdef DEBUG
|
||||
// display the gradient position:
|
||||
std::shared_ptr<esvg::render::DynamicColorLinear> tmpColor = std::dynamic_pointer_cast<esvg::render::DynamicColorLinear>(_colorFill);
|
||||
std::shared_ptr<esvg::render::DynamicColorSpecial> tmpColor = std::dynamic_pointer_cast<esvg::render::DynamicColorSpecial>(_colorFill);
|
||||
if (tmpColor != nullptr) {
|
||||
esvg::render::SegmentList listSegment;
|
||||
// Display bounding box
|
||||
|
@ -291,7 +291,7 @@ bool esvg::Document::parseXMLData(const std::shared_ptr<exml::Element>& _root, b
|
||||
ESVG_ERROR("'" << child->getValue() << "' node must not be defined outside a defs Section");
|
||||
continue;
|
||||
} else {
|
||||
//elementParser = std::make_shared<esvg::RadialGradient>(m_paint);
|
||||
elementParser = std::make_shared<esvg::RadialGradient>(m_paint);
|
||||
}
|
||||
} else if (child->getValue() == "linearGradient") {
|
||||
if (_isReference == false) {
|
||||
|
@ -9,19 +9,21 @@
|
||||
#include <esvg/debug.h>
|
||||
#include <esvg/render/DynamicColor.h>
|
||||
#include <esvg/LinearGradient.h>
|
||||
#include <esvg/RadialGradient.h>
|
||||
#include <esvg/esvg.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "render:DynamicColorLinear"
|
||||
#define __class__ "render:DynamicColorSpecial"
|
||||
|
||||
esvg::render::DynamicColorLinear::DynamicColorLinear(const std::string& _link, const mat2& _mtx) :
|
||||
esvg::render::DynamicColorSpecial::DynamicColorSpecial(const std::string& _link, const mat2& _mtx) :
|
||||
m_linear(true),
|
||||
m_colorName(_link),
|
||||
m_matrix(_mtx),
|
||||
m_viewPort(vec2(9999999999.0,9999999999.0),vec2(-9999999999.0,-9999999999.0)) {
|
||||
|
||||
}
|
||||
|
||||
void esvg::render::DynamicColorLinear::setViewPort(const std::pair<vec2, vec2>& _viewPort) {
|
||||
void esvg::render::DynamicColorSpecial::setViewPort(const std::pair<vec2, vec2>& _viewPort) {
|
||||
m_viewPort = _viewPort;
|
||||
}
|
||||
|
||||
@ -43,11 +45,19 @@ static vec2 getIntersect(const vec2& _point1,
|
||||
return _point2;
|
||||
}
|
||||
|
||||
// TODO : This can optimize ... really slow ... and not linear
|
||||
etk::Color<float,4> esvg::render::DynamicColorLinear::getColor(const ivec2& _pos) {
|
||||
etk::Color<float,4> esvg::render::DynamicColorSpecial::getColor(const ivec2& _pos) {
|
||||
if (m_data.size() < 2) {
|
||||
return etk::color::purple;
|
||||
}
|
||||
if (m_linear == true) {
|
||||
return getColorLinear(_pos);
|
||||
} else {
|
||||
return getColorRadial(_pos);
|
||||
}
|
||||
return etk::color::purple;
|
||||
}
|
||||
|
||||
etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorLinear(const ivec2& _pos) {
|
||||
float ratio = 0.0f;
|
||||
if (m_unit == gradientUnits_userSpaceOnUse) {
|
||||
vec2 vectorBase = m_pos2 - m_pos1;
|
||||
@ -146,7 +156,73 @@ etk::Color<float,4> esvg::render::DynamicColorLinear::getColor(const ivec2& _pos
|
||||
return etk::color::green;
|
||||
}
|
||||
|
||||
void esvg::render::DynamicColorLinear::generate(esvg::Document* _document) {
|
||||
etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorRadial(const ivec2& _pos) {
|
||||
float ratio = 0.0f;
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 intersecX = getIntersect(m_pos1, m_axeX,
|
||||
vec2(_pos.x(), _pos.y()), m_axeY);
|
||||
vec2 intersecY = getIntersect(m_pos1, m_axeY,
|
||||
vec2(_pos.x(), _pos.y()), m_axeX);
|
||||
vec2 vectorBaseDrawX = intersecX - m_pos1;
|
||||
vec2 vectorBaseDrawY = intersecY - m_pos1;
|
||||
float baseDrawX = vectorBaseDrawX.length();
|
||||
float baseDrawY = vectorBaseDrawY.length();
|
||||
ratio = vec2(baseDrawX, baseDrawY).length();
|
||||
if (m_baseSize.x()+m_baseSize.y() != 0.0f) {
|
||||
ratio /= 100.0f;//(m_baseSize.x()*m_baseSize.y());
|
||||
} else {
|
||||
ratio = 1.0f;
|
||||
}
|
||||
if (m_baseSize.x()+m_baseSize.y() != 0.0f) {
|
||||
if ( m_baseSize.x() != 0.0f
|
||||
&& m_baseSize.y() != 0.0f) {
|
||||
ratio = vec2(baseDrawX/m_baseSize.x(), baseDrawY/m_baseSize.y()).length();
|
||||
} else if (m_baseSize.x() != 0.0f) {
|
||||
ratio = baseDrawX/m_baseSize.x();
|
||||
} else {
|
||||
ratio = baseDrawY/m_baseSize.y();
|
||||
}
|
||||
} else {
|
||||
ratio = 1.0f;
|
||||
}
|
||||
switch(m_spread) {
|
||||
case spreadMethod_pad:
|
||||
// nothing to do ...
|
||||
break;
|
||||
case spreadMethod_reflect:
|
||||
ratio -= float((int32_t(ratio)>>1)<<1);
|
||||
if (ratio > 1.0f) {
|
||||
ratio = 2.0f-ratio;
|
||||
}
|
||||
break;
|
||||
case spreadMethod_repeat:
|
||||
ratio -= float(int32_t(ratio));
|
||||
if (ratio <0.0f) {
|
||||
ratio = 1.0f-std::abs(ratio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ratio <= m_data[0].first*0.01f) {
|
||||
return m_data[0].second;
|
||||
}
|
||||
if (ratio >= m_data.back().first*0.01f) {
|
||||
return m_data.back().second;
|
||||
}
|
||||
for (size_t iii=1; iii<m_data.size(); ++iii) {
|
||||
if (ratio <= m_data[iii].first*0.01f) {
|
||||
float localRatio = ratio - m_data[iii-1].first*0.01f;
|
||||
localRatio = localRatio / ((m_data[iii].first - m_data[iii-1].first) * 0.01f);
|
||||
return etk::Color<float,4>(m_data[iii-1].second.r() * (1.0-localRatio) + m_data[iii].second.r() * localRatio,
|
||||
m_data[iii-1].second.g() * (1.0-localRatio) + m_data[iii].second.g() * localRatio,
|
||||
m_data[iii-1].second.b() * (1.0-localRatio) + m_data[iii].second.b() * localRatio,
|
||||
m_data[iii-1].second.a() * (1.0-localRatio) + m_data[iii].second.a() * localRatio);
|
||||
}
|
||||
}
|
||||
return etk::color::green;
|
||||
}
|
||||
|
||||
|
||||
void esvg::render::DynamicColorSpecial::generate(esvg::Document* _document) {
|
||||
if (_document == nullptr) {
|
||||
ESVG_ERROR("Get nullptr input for document");
|
||||
return;
|
||||
@ -156,57 +232,117 @@ void esvg::render::DynamicColorLinear::generate(esvg::Document* _document) {
|
||||
ESVG_ERROR("Can not get base : '" << m_colorName << "'");
|
||||
return;
|
||||
}
|
||||
// Now we can know if we use linear or radial gradient ...
|
||||
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_colorName << "' ==> wrong type");
|
||||
return;
|
||||
}
|
||||
ESVG_INFO("get for color linear:");
|
||||
gradient->display(2);
|
||||
m_unit = gradient->m_unit;
|
||||
m_spread = gradient->m_spread;
|
||||
ESVG_INFO(" viewport = {" << m_viewPort.first << "," << m_viewPort.second << "}");
|
||||
vec2 size = m_viewPort.second - m_viewPort.first;
|
||||
|
||||
esvg::Dimension dimPos1 = gradient->getPosition1();
|
||||
m_pos1 = dimPos1.getPixel(size);
|
||||
if (dimPos1.getType() == esvg::distance_pourcent) {
|
||||
m_pos1 += m_viewPort.first;
|
||||
}
|
||||
esvg::Dimension dimPos2 = gradient->getPosition2();
|
||||
m_pos2 = dimPos2.getPixel(size);
|
||||
if (dimPos2.getType() == esvg::distance_pourcent) {
|
||||
m_pos2 += m_viewPort.first;
|
||||
}
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 delta = m_pos2 - m_pos1;
|
||||
if (delta.x() < 0.0f) {
|
||||
m_axeX = vec2(-1.0f, 0.0f);
|
||||
if (gradient != nullptr) {
|
||||
m_linear = true;
|
||||
ESVG_INFO("get for color linear:");
|
||||
gradient->display(2);
|
||||
m_unit = gradient->m_unit;
|
||||
m_spread = gradient->m_spread;
|
||||
ESVG_INFO(" viewport = {" << m_viewPort.first << "," << m_viewPort.second << "}");
|
||||
vec2 size = m_viewPort.second - m_viewPort.first;
|
||||
|
||||
esvg::Dimension dimPos1 = gradient->getPosition1();
|
||||
m_pos1 = dimPos1.getPixel(size);
|
||||
if (dimPos1.getType() == esvg::distance_pourcent) {
|
||||
m_pos1 += m_viewPort.first;
|
||||
}
|
||||
esvg::Dimension dimPos2 = gradient->getPosition2();
|
||||
m_pos2 = dimPos2.getPixel(size);
|
||||
if (dimPos2.getType() == esvg::distance_pourcent) {
|
||||
m_pos2 += m_viewPort.first;
|
||||
}
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 delta = m_pos2 - m_pos1;
|
||||
if (delta.x() < 0.0f) {
|
||||
m_axeX = vec2(-1.0f, 0.0f);
|
||||
} else {
|
||||
m_axeX = vec2(1.0f, 0.0f);
|
||||
}
|
||||
if (delta.y() < 0.0f) {
|
||||
m_axeY = vec2(0.0f, -1.0f);
|
||||
} else {
|
||||
m_axeY = vec2(0.0f, 1.0f);
|
||||
}
|
||||
// Move the positions ...
|
||||
m_pos1 = m_matrix * m_pos1;
|
||||
m_pos2 = m_matrix * m_pos2;
|
||||
m_axeX = m_matrix.applyScaleRotation(m_axeX);
|
||||
m_axeY = m_matrix.applyScaleRotation(m_axeY);
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 intersecX = getIntersect(m_pos1, m_axeX,
|
||||
m_pos2, m_axeY);
|
||||
vec2 intersecY = getIntersect(m_pos1, m_axeY,
|
||||
m_pos2, m_axeX);
|
||||
m_baseSize = vec2((m_pos1 - intersecX).length(),
|
||||
(m_pos1 - intersecY).length());
|
||||
// get all the colors
|
||||
m_data = gradient->getColors(_document);
|
||||
} else {
|
||||
m_axeX = vec2(1.0f, 0.0f);
|
||||
m_linear = false;
|
||||
std::shared_ptr<esvg::RadialGradient> gradient = std::dynamic_pointer_cast<esvg::RadialGradient>(base);
|
||||
if (gradient == nullptr) {
|
||||
ESVG_ERROR("Can not cast in a linear gradient: '" << m_colorName << "' ==> wrong type");
|
||||
return;
|
||||
}
|
||||
ESVG_INFO("get for color Radial:");
|
||||
gradient->display(2);
|
||||
m_unit = gradient->m_unit;
|
||||
m_spread = gradient->m_spread;
|
||||
ESVG_INFO(" viewport = {" << m_viewPort.first << "," << m_viewPort.second << "}");
|
||||
vec2 size = m_viewPort.second - m_viewPort.first;
|
||||
|
||||
esvg::Dimension dimCenter = gradient->getCenter();
|
||||
m_pos1 = dimCenter.getPixel(size);
|
||||
if (dimCenter.getType() == esvg::distance_pourcent) {
|
||||
m_pos1 += m_viewPort.first;
|
||||
}
|
||||
esvg::Dimension dimFocal = gradient->getFocal();
|
||||
m_focal = dimFocal.getPixel(size);
|
||||
if (dimFocal.getType() == esvg::distance_pourcent) {
|
||||
m_focal += m_viewPort.first;
|
||||
}
|
||||
esvg::Dimension1D dimRadius = gradient->getRadius();
|
||||
m_pos2.setX(dimRadius.getPixel(size.x()));
|
||||
m_pos2.setY(dimRadius.getPixel(size.y()));
|
||||
m_pos2 += m_pos1;
|
||||
/*
|
||||
if (dimRadius.getType() == esvg::distance_pourcent) {
|
||||
m_pos2 += m_viewPort.first;
|
||||
}
|
||||
*/
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 delta = m_pos1 - m_pos2;
|
||||
if (delta.x() < 0.0f) {
|
||||
m_axeX = vec2(-1.0f, 0.0f);
|
||||
} else {
|
||||
m_axeX = vec2(1.0f, 0.0f);
|
||||
}
|
||||
if (delta.y() < 0.0f) {
|
||||
m_axeY = vec2(0.0f, -1.0f);
|
||||
} else {
|
||||
m_axeY = vec2(0.0f, 1.0f);
|
||||
}
|
||||
// Move the positions ...
|
||||
m_pos1 = m_matrix * m_pos1;
|
||||
m_focal = m_matrix * m_focal;
|
||||
m_pos2 = m_matrix * m_pos2;
|
||||
m_axeX = m_matrix.applyScaleRotation(m_axeX);
|
||||
m_axeY = m_matrix.applyScaleRotation(m_axeY);
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 intersecX = getIntersect(m_pos1, m_axeX,
|
||||
m_pos2, m_axeY);
|
||||
vec2 intersecY = getIntersect(m_pos1, m_axeY,
|
||||
m_pos2, m_axeX);
|
||||
m_baseSize = vec2((m_pos1 - intersecX).length(),
|
||||
(m_pos1 - intersecY).length());
|
||||
ESVG_VERBOSE("baseSize=" << m_baseSize << " m_pos1=" << m_pos1 << " dim=" << dimCenter << " m_focal=" << m_focal << " m_pos2=" << m_pos2 << " dim=" << dimRadius);
|
||||
// get all the colors
|
||||
m_data = gradient->getColors(_document);
|
||||
}
|
||||
if (delta.y() < 0.0f) {
|
||||
m_axeY = vec2(0.0f, -1.0f);
|
||||
} else {
|
||||
m_axeY = vec2(0.0f, 1.0f);
|
||||
}
|
||||
// Move the positions ...
|
||||
m_pos1 = m_matrix * m_pos1;
|
||||
m_pos2 = m_matrix * m_pos2;
|
||||
m_axeX = m_matrix.applyScaleRotation(m_axeX);
|
||||
m_axeY = m_matrix.applyScaleRotation(m_axeY);
|
||||
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
|
||||
vec2 intersecX = getIntersect(m_pos1, m_axeX,
|
||||
m_pos2, m_axeY);
|
||||
vec2 intersecY = getIntersect(m_pos1, m_axeY,
|
||||
m_pos2, m_axeX);
|
||||
m_baseSize = vec2((m_pos1 - intersecX).length(),
|
||||
(m_pos1 - intersecY).length());
|
||||
// get all the colors
|
||||
m_data = gradient->getColors(_document);
|
||||
}
|
||||
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "render:DynamicColor"
|
||||
|
||||
@ -217,7 +353,7 @@ std::shared_ptr<esvg::render::DynamicColor> esvg::render::createColor(std::pair<
|
||||
return nullptr;
|
||||
}
|
||||
if (_color.second != "") {
|
||||
return std::make_shared<esvg::render::DynamicColorLinear>(_color.second, _mtx);
|
||||
return std::make_shared<esvg::render::DynamicColorSpecial>(_color.second, _mtx);
|
||||
}
|
||||
return std::make_shared<esvg::render::DynamicColorUni>(_color.first);
|
||||
}
|
||||
|
@ -48,22 +48,28 @@ namespace esvg {
|
||||
// nothing to do ...
|
||||
};
|
||||
};
|
||||
class DynamicColorLinear : public esvg::render::DynamicColor {
|
||||
class DynamicColorSpecial : public esvg::render::DynamicColor {
|
||||
public:
|
||||
bool m_linear;
|
||||
esvg::spreadMethod m_spread;
|
||||
esvg::gradientUnits m_unit;
|
||||
std::string m_colorName;
|
||||
mat2 m_matrix;
|
||||
std::pair<vec2, vec2> m_viewPort;
|
||||
vec2 m_pos1;
|
||||
vec2 m_pos2;
|
||||
vec2 m_pos1; // in radius ==> center
|
||||
vec2 m_pos2; // in radius ==> radius end position
|
||||
vec2 m_focal; // Specific radius
|
||||
vec2 m_axeX;
|
||||
vec2 m_axeY;
|
||||
vec2 m_baseSize;
|
||||
std::vector<std::pair<float, etk::Color<float,4>>> m_data;
|
||||
public:
|
||||
DynamicColorLinear(const std::string& _link, const mat2& _mtx);
|
||||
DynamicColorSpecial(const std::string& _link, const mat2& _mtx);
|
||||
virtual etk::Color<float,4> getColor(const ivec2& _pos);
|
||||
private:
|
||||
etk::Color<float,4> getColorLinear(const ivec2& _pos);
|
||||
etk::Color<float,4> getColorRadial(const ivec2& _pos);
|
||||
public:
|
||||
virtual void generate(esvg::Document* _document);
|
||||
virtual void setViewPort(const std::pair<vec2, vec2>& _viewPort);
|
||||
};
|
||||
|
@ -259,7 +259,7 @@ TEST(TestGradientLinear, unitBox_spreadReflect) {
|
||||
}
|
||||
|
||||
|
||||
TEST(TestGradientLinear, unitBox_spreadRepeate) {
|
||||
TEST(TestGradientLinear, unitBox_spreadRepeat) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
@ -272,8 +272,8 @@ TEST(TestGradientLinear, unitBox_spreadRepeate) {
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientLinear_unitBox_spreadRepeate.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientLinear_unitBox_spreadRepeate.bmp", g_visualDebug);
|
||||
etk::FSNodeWriteAllData("TestGradientLinear_unitBox_spreadRepeat.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientLinear_unitBox_spreadRepeat.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
TEST(TestGradientLinear, unitUser_spreadNone) {
|
||||
|
@ -13,13 +13,35 @@
|
||||
#undef __class__
|
||||
#define __class__ "TestGradientRadial"
|
||||
|
||||
TEST(TestGradientRadial, circle) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50%' cy='50%' r='50%' fx='50%' fy='50%'>\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='50' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_circle.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_circle.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestGradientRadial, full) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50%' cy='50%' r='50%' fx='50%' fy='50%'>\n"
|
||||
" <stop offset='0%' style='stop-color:rgb(255,255,255);stop-opacity:0' />\n"
|
||||
" <stop offset='100%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
@ -36,8 +58,10 @@ TEST(TestGradientRadial, partial) {
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad2' cx='20%' cy='30%' r='30%' fx='50%' fy='50%'>\n"
|
||||
" <stop offset='0%' style='stop-color:rgb(255,255,255);stop-opacity:0' />\n"
|
||||
" <stop offset='100%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n"
|
||||
@ -46,4 +70,161 @@ TEST(TestGradientRadial, partial) {
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_partial.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_partial.bmp", g_visualDebug);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestGradientRadial, unitBox_spreadNone) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50%' cy='50%' r='10%' fx='50%' fy='50%'>\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitBox_spreadNone.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitBox_spreadNone.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
TEST(TestGradientRadial, unitBox_spreadPad) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50%' cy='50%' r='10%' fx='50%' fy='50%' spreadMethod='pad'>\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitBox_spreadPad.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitBox_spreadPad.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
TEST(TestGradientRadial, unitBox_spreadReflect) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50%' cy='50%' r='10%' fx='50%' fy='50%' spreadMethod='reflect'>\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitBox_spreadReflect.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitBox_spreadReflect.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestGradientRadial, unitBox_spreadRepeat) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50%' cy='50%' r='10%' fx='50%' fy='50%' spreadMethod='repeat'>\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitBox_spreadRepeat.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitBox_spreadRepeat.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestGradientRadial, unitUser_spreadNone) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50' cy='50' r='10' fx='50' fy='50%' gradientUnits='userSpaceOnUse' >\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitUser_spreadNone.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitUser_spreadNone.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
TEST(TestGradientRadial, unitUser_spreadPad) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50' cy='50' r='10' fx='50' fy='50' spreadMethod='pad' gradientUnits='userSpaceOnUse' >\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitUser_spreadPad.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitUser_spreadPad.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
TEST(TestGradientRadial, unitUser_spreadReflect) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50' cy='50' r='10' fx='50' fy='50' spreadMethod='reflect' gradientUnits='userSpaceOnUse' >\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitUser_spreadReflect.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitUser_spreadReflect.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestGradientRadial, unitUser_spreadRepeat) {
|
||||
std::string data("<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||
"<svg height='100' width='100'>\n"
|
||||
" <defs>\n"
|
||||
" <radialGradient id='grad1' cx='50' cy='50' r='10' fx='50' fy='50' spreadMethod='repeat' gradientUnits='userSpaceOnUse' >\n"
|
||||
" <stop offset='0%' style='stop-color:orange;stop-opacity:1' />\n"
|
||||
" <stop offset='45%' style='stop-color:red;stop-opacity:1' />\n"
|
||||
" <stop offset='55%' style='stop-color:blue;stop-opacity:1' />\n"
|
||||
" <stop offset='100%' style='stop-color:green;stop-opacity:1' />\n"
|
||||
" </radialGradient>\n"
|
||||
" </defs>\n"
|
||||
" <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
|
||||
"</svg>\n");
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientRadial_unitUser_spreadRepeat.svg", data);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientRadial_unitUser_spreadRepeat.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user